From 5b5d11eab13a4f7054e187f6621f2e129602d3f9 Mon Sep 17 00:00:00 2001 From: sthoene Date: Fri, 1 Aug 2025 15:31:48 +0200 Subject: [PATCH 01/47] refactor BaseSensorClass --- src/ansys/speos/core/generic/constants.py | 38 ++++ src/ansys/speos/core/sensor.py | 236 +++++++++++++++------- 2 files changed, 199 insertions(+), 75 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index bea4e940c..4cca3ff33 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -38,3 +38,41 @@ """Maximum message Size accepted by grpc channel, By default, 4194304. """ + + +class SENSOR: + """Constant class for Sensors.""" + + class WAVELENGTHSRANGE: + """Wavelength constants.""" + + START = 400 + """Wavelength start value.""" + END = 700 + """Wavelength end value.""" + SAMPLING = 13 + """Wavelength sampling.""" + + class DIMENSIONS: + """Dimension Constants.""" + + X_START = -50 + """Lower bound x axis.""" + X_END = 50 + """Upper bound x axis.""" + X_SAMPLING = 100 + """Sampling x axis.""" + Y_START = -50 + """Lower bound y axis.""" + Y_END = 50 + """Upper bound y axis.""" + Y_SAMPLING = 100 + """Sampling y axis.""" + + class LAYERTYPES: + """Layer Separation constants.""" + + MAXIMUM_NB_OF_SEQUENCE = 10 + """Number of sequences stored in sensor.""" + INCIDENCE_SAMPLING = 9 + """Number of incidence sampling stored in sensor""" diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index ae122bfd6..d24e1ac25 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -34,6 +34,7 @@ from ansys.api.speos.sensor.v1 import camera_sensor_pb2, common_pb2, sensor_pb2 import ansys.speos.core as core +from ansys.speos.core.generic.constants import SENSOR import ansys.speos.core.generic.general_methods as general_methods from ansys.speos.core.generic.visualization_methods import _VisualData, local2absolute from ansys.speos.core.geo_ref import GeoRef @@ -160,49 +161,68 @@ def __init__( if default_values: # Default values - self.set_start().set_end().set_sampling() + self.start = SENSOR.WAVELENGTHSRANGE.START + self.end = SENSOR.WAVELENGTHSRANGE.END + self.sampling = SENSOR.WAVELENGTHSRANGE.SAMPLING - def set_start(self, value: float = 400) -> BaseSensor.WavelengthsRange: + @property + def start(self) -> float: + """The minimum wavelength of the range.""" + if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): + return self._wavelengths_range.w_start + else: + return self._wavelengths_range.wavelength_start + + @start.setter + def start(self, value: float): """Set the minimum wavelength of the range. Parameters ---------- value : float Minimum wavelength (nm). - By default, ``400``. - - Returns - ------- - ansys.speos.core.sensor.BaseSensor.WavelengthsRange - WavelengthsRange. """ if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): self._wavelengths_range.w_start = value else: self._wavelengths_range.wavelength_start = value - return self - def set_end(self, value: float = 700) -> BaseSensor.WavelengthsRange: + @property + def end(self) -> float: + """Set the maximum wavelength of the range. + + By default, ``700``. + """ + if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): + return self._wavelengths_range.w_end + else: + return self._wavelengths_range.wavelength_end + + @end.setter + def end(self, value: float): """Set the maximum wavelength of the range. Parameters ---------- value : float Maximum wavelength (nm). - By default, ``700``. - - Returns - ------- - ansys.speos.core.sensor.BaseSensor.WavelengthsRange - WavelengthsRange. """ if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): self._wavelengths_range.w_end = value else: self._wavelengths_range.wavelength_end = value - return self - def set_sampling(self, value: int = 13) -> BaseSensor.WavelengthsRange: + @property + def sampling(self) -> int: + """Set the sampling of wavelengths range. + + By default, ``13``. + """ + if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): + return self._wavelengths_range.w_sampling + + @sampling.setter + def sampling(self, value: int = 13): """Set the sampling of wavelengths range. Parameters @@ -210,16 +230,9 @@ def set_sampling(self, value: int = 13) -> BaseSensor.WavelengthsRange: value : int Number of wavelengths to be taken into account between the minimum and maximum wavelengths range. - By default, ``13``. - - Returns - ------- - ansys.speos.core.sensor.BaseSensor.WavelengthsRange - WavelengthsRange. """ if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): self._wavelengths_range.w_sampling = value - return self class Dimensions: """Dimensions of the sensor. @@ -254,109 +267,156 @@ def __init__( if default_values: # Default values - self.set_x_start().set_x_end().set_x_sampling().set_y_start().set_y_end().set_y_sampling() + self.x_start = SENSOR.DIMENSIONS.X_START + self.y_start = SENSOR.DIMENSIONS.Y_START + self.x_end = SENSOR.DIMENSIONS.X_END + self.y_end = SENSOR.DIMENSIONS.Y_END + self.x_sampling = SENSOR.DIMENSIONS.X_SAMPLING + self.y_sampling = SENSOR.DIMENSIONS.Y_SAMPLING - def set_x_start(self, value: float = -50) -> BaseSensor.Dimensions: + @property + def x_start(self) -> float: + """Set the minimum value on x axis. + + By default, ``-50``. + + Returns + ------- + float + minimum value in x axis + """ + return self._sensor_dimensions.x_start + + @x_start.setter + def x_start(self, value: float): """Set the minimum value on x axis. Parameters ---------- value : float Minimum value on x axis (mm). - By default, ``-50``. + """ + self._sensor_dimensions.x_start = value + + @property + def x_end(self) -> float: + """Set the maximum value on x axis. + + By default, ``50``. Returns ------- - ansys.speos.core.sensor.BaseSensor.Dimensions - Dimensions. + float + maximum value on x axis. """ - self._sensor_dimensions.x_start = value - return self + return self._sensor_dimensions.x_end - def set_x_end(self, value: float = 50) -> BaseSensor.Dimensions: + @x_end.setter + def x_end(self, value: float): """Set the maximum value on x axis. Parameters ---------- value : float Maximum value on x axis (mm). - By default, ``50``. + """ + self._sensor_dimensions.x_end = value + + @property + def x_sampling(self) -> int: + """Set the sampling value on x axis. + + By default, ``100``. Returns ------- - ansys.speos.core.sensor.BaseSensor.Dimensions - Dimensions. + float + sampling value on x axis. """ - self._sensor_dimensions.x_end = value - return self + return self._sensor_dimensions.x_sampling - def set_x_sampling(self, value: int = 100) -> BaseSensor.Dimensions: + @x_sampling.setter + def x_sampling(self, value: int): """Set the sampling value on x axis. Parameters ---------- value : int The number of pixels of the XMP map on x axis. - By default, ``100``. + """ + self._sensor_dimensions.x_sampling = value + + @property + def y_start(self) -> float: + """Set the minimum value on y axis. + + By default, ``-50``. Returns ------- - ansys.speos.core.sensor.BaseSensor.Dimensions - Dimensions. + float + minimum value in y axis """ - self._sensor_dimensions.x_sampling = value - return self + return self._sensor_dimensions.y_start - def set_y_start(self, value: float = -50) -> BaseSensor.Dimensions: + @y_start.setter + def y_start(self, value: float): """Set the minimum value on y axis. Parameters ---------- value : float Minimum value on y axis (mm). - By default, ``-50``. + """ + self._sensor_dimensions.y_start = value + + @property + def y_end(self) -> float: + """Set the maximum value on y axis. + + By default, ``50``. Returns ------- - ansys.speos.core.sensor.BaseSensor.Dimensions - Dimensions. + float + maximum value on y axis. """ - self._sensor_dimensions.y_start = value - return self + return self._sensor_dimensions.y_end - def set_y_end(self, value: float = 50) -> BaseSensor.Dimensions: + @y_end.setter + def y_end(self, value: float): """Set the maximum value on y axis. Parameters ---------- value : float Maximum value on y axis (mm). - By default, ``50``. + """ + self._sensor_dimensions.y_end = value + + @property + def y_sampling(self) -> int: + """Set the sampling value on y axis. + + By default, ``100``. Returns ------- - ansys.speos.core.sensor.BaseSensor.Dimensions - Dimensions. + float + sampling value on y axis. """ - self._sensor_dimensions.y_end = value - return self + return self._sensor_dimensions.y_sampling - def set_y_sampling(self, value: int = 100) -> BaseSensor.Dimensions: + @y_sampling.setter + def y_sampling(self, value: int): """Set the sampling value on y axis. Parameters ---------- value : int The number of pixels of the XMP map on y axis. - By default, ``100``. - - Returns - ------- - ansys.speos.core.sensor.BaseSensor.Dimensions - Dimensions. """ self._sensor_dimensions.y_sampling = value - return self class Colorimetric: """Type of sensor : Colorimetric. @@ -567,6 +627,7 @@ def set_sca_filtering_mode_last_impact( ) return self + # @TODO "refactor to property" def set_layers(self, values: List[BaseSensor.FaceLayer]) -> BaseSensor.LayerTypeFace: """Set the layers. @@ -629,24 +690,32 @@ def __init__( if default_values: # Default values - self.set_maximum_nb_of_sequence().set_define_sequence_per_geometries() + self.maximum_nb_of_sequence = SENSOR.LAYERTYPES.MAXIMUM_NB_OF_SEQUENCE + self.set_define_sequence_per_geometries() - def set_maximum_nb_of_sequence(self, value: int = 10) -> BaseSensor.LayerTypeSequence: + @property + def maximum_nb_of_sequence(self) -> int: + """Set the maximum number of sequences. + + By default, ``10``. + + Returns + ------- + int + maximum number of sequences. + """ + return self._layer_type_sequence.maximum_nb_of_sequence + + @maximum_nb_of_sequence.setter + def maximum_nb_of_sequence(self, value: int): """Set the maximum number of sequences. Parameters ---------- value : int Maximum number of sequences. - By default, ``10``. - - Returns - ------- - ansys.speos.core.sensor.BaseSensor.LayerTypeSequence - LayerTypeSequence. """ self._layer_type_sequence.maximum_nb_of_sequence = value - return self def set_define_sequence_per_geometries( self, @@ -714,7 +783,25 @@ def __init__( # Default values self.set_sampling() - def set_sampling(self, value: int = 9) -> BaseSensor.LayerTypeIncidenceAngle: + @property + def sampling(self) -> BaseSensor.LayerTypeIncidenceAngle: + """Set the sampling for incidence angles. + + Parameters + ---------- + value : int + Sampling for incidence angles. + By default, ``9``. + + Returns + ------- + ansys.speos.core.sensor.BaseSensor.LayerTypeIncidenceAngle + LayerTypeIncidenceAngle. + """ + return self._layer_type_incidence_angle.sampling + + @sampling.setter + def sampling(self, value: int) -> BaseSensor.LayerTypeIncidenceAngle: """Set the sampling for incidence angles. Parameters @@ -729,7 +816,6 @@ def set_sampling(self, value: int = 9) -> BaseSensor.LayerTypeIncidenceAngle: LayerTypeIncidenceAngle. """ self._layer_type_incidence_angle.sampling = value - return self def _to_dict(self) -> dict: out_dict = {} From 862357df4d4c243b91ecd3cd3500c5db915ffadb Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 4 Aug 2025 09:24:45 +0200 Subject: [PATCH 02/47] refactor BalanceModeUserWhite --- src/ansys/speos/core/sensor.py | 86 ++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index d24e1ac25..6d3b3a604 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -34,12 +34,15 @@ from ansys.api.speos.sensor.v1 import camera_sensor_pb2, common_pb2, sensor_pb2 import ansys.speos.core as core +import ansys.speos.core.body as body +import ansys.speos.core.face as face from ansys.speos.core.generic.constants import SENSOR import ansys.speos.core.generic.general_methods as general_methods from ansys.speos.core.generic.visualization_methods import _VisualData, local2absolute from ansys.speos.core.geo_ref import GeoRef from ansys.speos.core.kernel.scene import ProtoScene from ansys.speos.core.kernel.sensor_template import ProtoSensorTemplate +import ansys.speos.core.part as part import ansys.speos.core.project as project import ansys.speos.core.proto_message_utils as proto_message_utils @@ -556,8 +559,22 @@ class FaceLayer: def __init__(self, name: str, geometries: List[GeoRef]) -> None: self.name = name """Name of the layer""" - self.geometries = geometries + self._geometries = geometries + + @property + def geometry(self): """List of geometries included in this layer.""" + return self._geometries + + @geometry.setter + def geometry(self, value): + geo_paths = [] + for gr in value: + if isinstance(gr, GeoRef): + geo_paths.append(gr) + elif isinstance(gr, (face.Face, body.Body, part.Part.SubPart)): + geo_paths.append(gr.geo_path) + self._geometries = geo_paths class LayerTypeFace: """Type of layer : Face. @@ -627,7 +644,6 @@ def set_sca_filtering_mode_last_impact( ) return self - # @TODO "refactor to property" def set_layers(self, values: List[BaseSensor.FaceLayer]) -> BaseSensor.LayerTypeFace: """Set the layers. @@ -1120,64 +1136,64 @@ def __init__( if default_values: # Default values - self.set_red_gain().set_green_gain().set_blue_gain() + self.red_gain = 1 + + @property + def red_gain(self) -> float: + """The red gain value of the Camera Sensor. - def set_red_gain( - self, value: float = 1 - ) -> SensorCamera.Photometric.Color.BalanceModeUserWhite: + By default, ``1``. + """ + return self._balance_mode_user_white.red_gain + + @red_gain.setter + def red_gain(self, value: float): """Set red gain. Parameters ---------- value : float Red gain. - By default, ``1``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color.BalanceModeUserWhite - BalanceModeUserWhite. """ self._balance_mode_user_white.red_gain = value - return self - def set_green_gain( - self, value: float = 1 - ) -> SensorCamera.Photometric.Color.BalanceModeUserWhite: + @property + def green_gain(self) -> float: + """The green gain value of the Camera Sensor. + + By default, ``1``. + """ + return self._balance_mode_user_white.green_gain + + @green_gain.setter + def green_gain(self, value: float): """Set green gain. Parameters ---------- value : float - Green gain. - By default, ``1``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color.BalanceModeUserWhite - BalanceModeUserWhite. + green gain. """ self._balance_mode_user_white.green_gain = value - return self - def set_blue_gain( - self, value: float = 1 - ) -> SensorCamera.Photometric.Color.BalanceModeUserWhite: + @property + def blue_gain(self) -> float: + """The bkue gain value of the Camera Sensor. + + By default, ``1``. + """ + return self._balance_mode_user_white.blue_gain + + @blue_gain.setter + def blue_gain(self, value: float): """Set blue gain. Parameters ---------- value : float - Blue gain. - By default, ``1``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color.BalanceModeUserWhite - BalanceModeUserWhite. + blue gain. """ self._balance_mode_user_white.blue_gain = value - return self class BalanceModeDisplayPrimaries: """BalanceMode : DisplayPrimaries. From 0e7800186664cc2b5d26bb42c9af5a0955b30db9 Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 4 Aug 2025 14:53:31 +0200 Subject: [PATCH 03/47] refactor sensor camera --- src/ansys/speos/core/sensor.py | 363 ++++++++++++++++++--------------- 1 file changed, 197 insertions(+), 166 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 6d3b3a604..970cc18dd 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -1137,6 +1137,8 @@ def __init__( if default_values: # Default values self.red_gain = 1 + self.green_gain = 1 + self.blue_gain = 1 @property def red_gain(self) -> float: @@ -1236,59 +1238,53 @@ def __init__( # Default values self._balance_mode_display.SetInParent() - def set_red_display_file_uri( - self, uri: str - ) -> SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries: + @property + def red_display_file_uri(self) -> str: + """The red display file.""" + return self._balance_mode_display.red_display_file_uri + + @red_display_file_uri.setter + def red_display_file_uri(self, uri: str): """Set the red display file. Parameters ---------- uri : str Red display file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries - BalanceModeDisplayPrimaries. """ self._balance_mode_display.red_display_file_uri = uri - return self - def set_green_display_file_uri( - self, uri: str - ) -> SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries: + @property + def green_display_file_uri(self) -> str: + """The green display file.""" + return self._balance_mode_display.green_display_file_uri + + @green_display_file_uri.setter + def green_display_file_uri(self, uri: str): """Set the green display file. Parameters ---------- uri : str - Green display file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries - BalanceModeDisplayPrimaries. + green display file. """ self._balance_mode_display.green_display_file_uri = uri - return self - def set_blue_display_file_uri( - self, uri: str - ) -> SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries: + @property + def blue_display_file_uri(self) -> str: + """The blue display file.""" + return self._balance_mode_display.blue_display_file_uri + + @blue_display_file_uri.setter + def blue_display_file_uri(self, uri: str): """Set the blue display file. Parameters ---------- uri : str - Blue display file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries - BalanceModeDisplayPrimaries. + blue display file. """ self._balance_mode_display.blue_display_file_uri = uri - return self def __init__( self, @@ -1308,53 +1304,53 @@ def __init__( # Default values self.set_balance_mode_none() - def set_red_spectrum_file_uri(self, uri: str) -> SensorCamera.Photometric.Color: + @property + def red_spectrum_file_uri(self) -> str: + """The red spectrum.""" + return self._mode_color.red_spectrum_file_uri + + @red_spectrum_file_uri.setter + def red_spectrum_file_uri(self, uri: str): """Set the red spectrum. Parameters ---------- uri : str Red spectrum file. It is expressed in a .spectrum file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color - Color mode. """ self._mode_color.red_spectrum_file_uri = uri - return self - def set_green_spectrum_file_uri(self, uri: str) -> SensorCamera.Photometric.Color: - """Set the green spectrum. + @property + def blue_spectrum_file_uri(self) -> str: + """The blue spectrum.""" + return self._mode_color.blue_spectrum_file_uri + + @blue_spectrum_file_uri.setter + def blue_spectrum_file_uri(self, uri: str): + """Set the blue spectrum. Parameters ---------- uri : str - Green spectrum file. It is expressed in a .spectrum file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color - Color mode. + blue spectrum file. It is expressed in a .spectrum file. """ - self._mode_color.green_spectrum_file_uri = uri - return self + self._mode_color.blue_spectrum_file_uri = uri - def set_blue_spectrum_file_uri(self, uri: str) -> SensorCamera.Photometric.Color: - """Set the blue spectrum. + @property + def green_spectrum_file_uri(self) -> str: + """The green spectrum.""" + return self._mode_color.green_spectrum_file_uri + + @green_spectrum_file_uri.setter + def green_spectrum_file_uri(self, uri: str): + """Set the green spectrum. Parameters ---------- uri : str - Blue spectrum file. It is expressed in a .spectrum file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric.Color - Color mode. + green spectrum file. It is expressed in a .spectrum file. """ - self._mode_color.blue_spectrum_file_uri = uri - return self + self._mode_color.green_spectrum_file_uri = uri def set_balance_mode_none(self) -> SensorCamera.Photometric.Color: """Set the balance mode as none. @@ -1486,12 +1482,23 @@ def __init__( if default_values: # Default values - self.set_acquisition_integration().set_acquisition_lag_time().set_gamma_correction().set_png_bits_16().set_mode_color() + self.acquisition_integration = 0.01 + self.acquisition_lag_time = 0.0 + self.set_gamma_correction().set_png_bits_16().set_mode_color() self.set_wavelengths_range() # Default values properties self.set_layer_type_none() - def set_acquisition_integration(self, value: float = 0.01) -> SensorCamera.Photometric: + @property + def acquisition_integration(self) -> float: + """The acquisition integration value. + + By default, ``0.01``. + """ + return self._mode_photometric.acquisition_integration + + @acquisition_integration.setter + def acquisition_integration(self, value: float): """Set the acquisition integration value. Parameters @@ -1499,16 +1506,19 @@ def set_acquisition_integration(self, value: float = 0.01) -> SensorCamera.Photo value : float Acquisition integration value (s). By default, ``0.01``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric - Photometric mode. """ self._mode_photometric.acquisition_integration = value - return self - def set_acquisition_lag_time(self, value: float = 0.0) -> SensorCamera.Photometric: + @property + def acquisition_lag_time(self, value: float = 0.0) -> float: + """The acquisition lag time value. + + By default, ``0.0``. + """ + return self._mode_photometric.acquisition_lag_time + + @acquisition_lag_time.setter + def acquisition_lag_time(self, value: float): """Set the acquisition lag time value. Parameters @@ -1523,9 +1533,14 @@ def set_acquisition_lag_time(self, value: float = 0.0) -> SensorCamera.Photometr Photometric mode. """ self._mode_photometric.acquisition_lag_time = value - return self - def set_transmittance_file_uri(self, uri: str) -> SensorCamera.Photometric: + @property + def transmittance_file_uri(self) -> str: + """The transmittance file.""" + return self._mode_photometric.transmittance_file_uri + + @transmittance_file_uri.setter + def transmittance_file_uri(self, uri: str): """Set the transmittance file. Parameters @@ -1533,31 +1548,24 @@ def set_transmittance_file_uri(self, uri: str) -> SensorCamera.Photometric: uri : str Amount of light of the source that passes through the lens and reaches the sensor. The transmittance is expressed in a .spectrum file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric - Photometric mode. """ self._mode_photometric.transmittance_file_uri = uri - return self - def set_gamma_correction(self, value: float = 2.2) -> SensorCamera.Photometric: + @property + def gamma_correction(self) -> float: """Set the gamma correction. - Parameters - ---------- - value : float - Compensation of the curve before the display on the screen. - By default, ``2.2``. + By default, ``2.2``. + """ + return self._mode_photometric.gamma_correction - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric - Photometric mode. + @gamma_correction.setter + def gamma_correction(self, value: float): + """Set the gamma correction. + + By default, ``2.2``. """ self._mode_photometric.gamma_correction = value - return self def set_png_bits_08(self) -> SensorCamera.Photometric: """Choose 08-bits for png. @@ -1668,7 +1676,13 @@ def set_mode_color(self) -> SensorCamera.Photometric.Color: self._mode._mode_color = self._mode_photometric.color_mode_color return self._mode - def set_trajectory_file_uri(self, uri: str) -> SensorCamera.Photometric: + @property + def trajectory_file_uri(self) -> str: + """The trajectory file.""" + return self._camera_props.trajectory_file_uri + + @trajectory_file_uri.setter + def trajectory_file_uri(self, uri: str): """Set the trajectory file. Parameters @@ -1676,14 +1690,8 @@ def set_trajectory_file_uri(self, uri: str) -> SensorCamera.Photometric: uri : str Trajectory file, used to define the position and orientations of the Camera sensor in time. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera.Photometric - Photometric mode. """ self._camera_props.trajectory_file_uri = uri - return self def set_layer_type_none(self) -> SensorCamera.Photometric: """Set no layer separation: includes the simulation's results in one layer. @@ -1836,7 +1844,16 @@ def photometric(self) -> Union[SensorCamera.Photometric, None]: """ return self._type - def set_focal_length(self, value: float = 5.0) -> SensorCamera: + @property + def focal_length(self) -> float: + """The focal length. + + By default, ``5.0``. + """ + return self._sensor_template.camera_sensor_template.focal_length + + @focal_length.setter + def focal_length(self, value: float) -> SensorCamera: """Set the focal length. Parameters @@ -1844,16 +1861,19 @@ def set_focal_length(self, value: float = 5.0) -> SensorCamera: value : float Distance between the center of the optical system and the focus. (mm) By default, ``5.0``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature """ self._sensor_template.camera_sensor_template.focal_length = value - return self - def set_imager_distance(self, value: float = 10) -> SensorCamera: + @property + def imager_distance(self, value: float = 10) -> SensorCamera: + """Set the imager distance. + + By default, ``10``. + """ + return self._sensor_template.camera_sensor_template.imager_distance + + @imager_distance.setter + def imager_distance(self, value: float): """Set the imager distance. Parameters @@ -1862,16 +1882,19 @@ def set_imager_distance(self, value: float = 10) -> SensorCamera: Imager distance (mm). The imager is located at the focal point. The Imager distance has no impact on the result. By default, ``10``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature """ self._sensor_template.camera_sensor_template.imager_distance = value - return self - def set_f_number(self, value: float = 20) -> SensorCamera: + @property + def f_number(self) -> float: + """Set the f number. + + By default, ``20``. + """ + return self._sensor_template.camera_sensor_template.f_number + + @f_number.setter + def f_number(self, value: float = 20): """Set the f number. Parameters @@ -1880,16 +1903,16 @@ def set_f_number(self, value: float = 20) -> SensorCamera: F-number represents the aperture of the front lens. F number has no impact on the result. By default, ``20``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature """ self._sensor_template.camera_sensor_template.f_number = value - return self - def set_distortion_file_uri(self, uri: str) -> SensorCamera: + @property + def distortion_file_uri(self) -> str: + """Set the distortion file.""" + return self._sensor_template.camera_sensor_template.distortion_file_uri + + @distortion_file_uri.setter + def distortion_file_uri(self, uri: str): """Set the distortion file. Parameters @@ -1897,16 +1920,16 @@ def set_distortion_file_uri(self, uri: str) -> SensorCamera: uri : str Optical aberration that deforms and bends straight lines. The distortion is expressed in a .OPTDistortion file. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature """ self._sensor_template.camera_sensor_template.distortion_file_uri = uri - return self - def set_horz_pixel(self, value: int = 640) -> SensorCamera: + @property + def horz_pixel(self) -> int: + """The horizontal pixels number corresponding to the camera resolution.""" + return self._sensor_template.camera_sensor_template.horz_pixel + + @horz_pixel.setter + def horz_pixel(self, value: int): """Set the horizontal pixels number corresponding to the camera resolution. Parameters @@ -1914,16 +1937,19 @@ def set_horz_pixel(self, value: int = 640) -> SensorCamera: value : int The horizontal pixels number corresponding to the camera resolution. By default, ``640``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature """ self._sensor_template.camera_sensor_template.horz_pixel = value - return self - def set_vert_pixel(self, value: int = 480) -> SensorCamera: + @property + def vert_pixel(self) -> int: + """The vertical pixels number corresponding to the camera resolution. + + By default, ``480``. + """ + return self._sensor_template.camera_sensor_template.vert_pixel + + @vert_pixel.setter + def vert_pixel(self, value: int): """Set the vertical pixels number corresponding to the camera resolution. Parameters @@ -1931,16 +1957,19 @@ def set_vert_pixel(self, value: int = 480) -> SensorCamera: value : int The vertical pixels number corresponding to the camera resolution. By default, ``480``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature """ self._sensor_template.camera_sensor_template.vert_pixel = value - return self - def set_width(self, value: float = 5.0) -> SensorCamera: + @property + def width(self) -> float: + """The width of the sensor. + + By default, ``5.0``. + """ + return self._sensor_template.camera_sensor_template.width + + @width.setter + def width(self, value: float): """Set the width of the sensor. Parameters @@ -1948,31 +1977,52 @@ def set_width(self, value: float = 5.0) -> SensorCamera: value : float Sensor's width (mm). By default, ``5.0``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature """ self._sensor_template.camera_sensor_template.width = value - return self - def set_height(self, value: float = 5.0) -> SensorCamera: - """Set the height of the sensor. + @property + def height(self) -> float: + """The height of the sensor. Parameters ---------- value : float Sensor's height (mm). By default, ``5.0``. + """ + return self._sensor_template.camera_sensor_template.height - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera feature + @height.setter + def height(self, value: float): + """Set the height of the sensor. + + Parameters + ---------- + value : float + Sensor's height (mm). + By default, ``5.0``. """ self._sensor_template.camera_sensor_template.height = value - return self + + @property + def axis_system(self, axis_system: List[float]) -> List[float]: + """The position of the sensor. + + By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + """ + return self._sensor_instance.camera_properties.axis_system + + @axis_system.setter + def axis_system(self, axis_system: List[float]): + """Set the position of the sensor. + + Parameters + ---------- + axis_system : Optional[List[float]] + Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. + By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + """ + self._sensor_instance.camera_properties.axis_system[:] = axis_system def set_mode_geometric(self) -> SensorCamera: """Set mode geometric for the camera sensor. @@ -2026,25 +2076,6 @@ def set_mode_photometric(self) -> SensorCamera.Photometric: ) return self._type - def set_axis_system(self, axis_system: Optional[List[float]] = None) -> SensorCamera: - """Set the position of the sensor. - - Parameters - ---------- - axis_system : Optional[List[float]] - Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. - By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. - - Returns - ------- - ansys.speos.core.sensor.SensorCamera - Camera Sensor feature - """ - if axis_system is None: - axis_system = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] - self._sensor_instance.camera_properties.axis_system[:] = axis_system - return self - def commit(self) -> SensorCamera: """Save feature: send the local data to the speos server database. From 736659903c65616407529a8cd44e1f4ebd1dc25a Mon Sep 17 00:00:00 2001 From: sthoene Date: Wed, 6 Aug 2025 11:36:05 +0200 Subject: [PATCH 04/47] add constants --- src/ansys/speos/core/generic/constants.py | 31 ++++++++++++++++++++- src/ansys/speos/core/sensor.py | 33 ++++++++++++++--------- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 4cca3ff33..0602c01de 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -39,6 +39,9 @@ By default, 4194304. """ +ORIGIN = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] +"""Global Origin""" + class SENSOR: """Constant class for Sensors.""" @@ -75,4 +78,30 @@ class LAYERTYPES: MAXIMUM_NB_OF_SEQUENCE = 10 """Number of sequences stored in sensor.""" INCIDENCE_SAMPLING = 9 - """Number of incidence sampling stored in sensor""" + """Number of incidence sampling stored in sensor.""" + + class CAMERASENSOR: + """Camera Sensor Constants.""" + + GAIN = 1 + """Default gain value of the Camera Sensor.""" + ACQUISITION_INTEGRATION = 0.01 + """Default integration Time value for the Camera Sensor.""" + ACQUISITION_LAG_TIME = 0 + """Default acquisition lag time for the Camera Sensor.""" + GAMMA_CORRECTION = 2.2 + """Default gamma correction Value for the Camera Sensor.""" + FOCAL_LENGTH = 5 + """Default focal length of the Camera Sensor.""" + IMAGER_DISTANCE = 10 + """Default imager distance of the camera sensor.""" + F_NUMBER = 20 + """Default f number of the camera sensor.""" + HORZ_PIXEL = 640 + """Default pixel number in horizontal direction.""" + VERT_PIXEL = 480 + """Default pixel number in vertical direction.""" + WIDTH = 5.0 + """Default width of the camera chip.""" + HEIGHT = 5.0 + """Default height of the camera chip.""" diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 970cc18dd..d15edf516 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -36,7 +36,7 @@ import ansys.speos.core as core import ansys.speos.core.body as body import ansys.speos.core.face as face -from ansys.speos.core.generic.constants import SENSOR +from ansys.speos.core.generic.constants import ORIGIN, SENSOR import ansys.speos.core.generic.general_methods as general_methods from ansys.speos.core.generic.visualization_methods import _VisualData, local2absolute from ansys.speos.core.geo_ref import GeoRef @@ -1136,9 +1136,9 @@ def __init__( if default_values: # Default values - self.red_gain = 1 - self.green_gain = 1 - self.blue_gain = 1 + self.red_gain = SENSOR.CAMERASENSOR.GAIN + self.green_gain = SENSOR.CAMERASENSOR.GAIN + self.blue_gain = SENSOR.CAMERASENSOR.GAIN @property def red_gain(self) -> float: @@ -1482,9 +1482,10 @@ def __init__( if default_values: # Default values - self.acquisition_integration = 0.01 - self.acquisition_lag_time = 0.0 - self.set_gamma_correction().set_png_bits_16().set_mode_color() + self.acquisition_integration = SENSOR.CAMERASENSOR.ACQUISITION_INTEGRATION + self.acquisition_lag_time = SENSOR.CAMERASENSOR.ACQUISITION_LAG_TIME + self.gamma_correction = SENSOR.CAMERASENSOR.GAMMA_CORRECTION + self.set_png_bits_16().set_mode_color() self.set_wavelengths_range() # Default values properties self.set_layer_type_none() @@ -1739,10 +1740,16 @@ def __init__( self._type = None if default_values: # Default values template - self.set_focal_length().set_imager_distance().set_f_number().set_horz_pixel() - self.set_vert_pixel().set_width().set_height().set_mode_photometric() - # Default values properties - self.set_axis_system() + self.imager_distance = SENSOR.CAMERASENSOR.IMAGER_DISTANCE + self.focal_length = SENSOR.CAMERASENSOR.FOCAL_LENGTH + self.f_number = SENSOR.CAMERASENSOR.F_NUMBER + self.horz_pixel = SENSOR.CAMERASENSOR.HORZ_PIXEL + self.vert_pixel = SENSOR.CAMERASENSOR.VERT_PIXEL + self.width = SENSOR.CAMERASENSOR.WIDTH + self.height = SENSOR.CAMERASENSOR.HEIGHT + self.axis_system = ORIGIN + + self.set_mode_photometric() @property def visual_data(self) -> _VisualData: @@ -1865,7 +1872,7 @@ def focal_length(self, value: float) -> SensorCamera: self._sensor_template.camera_sensor_template.focal_length = value @property - def imager_distance(self, value: float = 10) -> SensorCamera: + def imager_distance(self) -> SensorCamera: """Set the imager distance. By default, ``10``. @@ -2005,7 +2012,7 @@ def height(self, value: float): self._sensor_template.camera_sensor_template.height = value @property - def axis_system(self, axis_system: List[float]) -> List[float]: + def axis_system(self) -> List[float]: """The position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. From 0500a97be060107086800dce2149af129ebf6c4f Mon Sep 17 00:00:00 2001 From: sthoene Date: Wed, 6 Aug 2025 12:06:21 +0200 Subject: [PATCH 05/47] Refactor Irradiance Sensor --- src/ansys/speos/core/sensor.py | 132 +++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 40 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index d15edf516..7b42b7ac5 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -2181,7 +2181,8 @@ def __init__( # Default values template self.set_type_photometric().set_illuminance_type_planar() # Default values properties - self.set_axis_system().set_ray_file_type_none().set_layer_type_none() + self.axis_system = ORIGIN + self.set_ray_file_type_none().set_layer_type_none() @property def visual_data(self) -> _VisualData: @@ -2438,9 +2439,52 @@ def set_type_spectral(self) -> BaseSensor.Spectral: ) return self._type - def set_illuminance_type_planar( - self, integration_direction: Optional[List[float]] = None - ) -> SensorIrradiance: + @property + def integration_direction(self): + """Integration direction of irradiance Sensor. + + Sensor global integration direction [x,y,z], optional (default direction is Z axis of + axis_system). + + Note: Contrary to any visualization of integration directions within Speos Software or its + documentation the integration direction must be set in the anti-rays direction to integrate + their signal. + Integration direction is only settable for sensor template with IlluminanceTypePlanar or + IlluminanceTypeSemiCylindrical as illuminance_type + + Returns + ------- + List[float] + Sensor global integration direction [x,y,z] + """ + return self._sensor_instance.irradiance_properties.integration_direction + + @integration_direction.setter + def integration_direction(self, value: List[float]): + """Set integration direction. + + Parameters + ---------- + value : List[float] + Sensor global integration direction [x,y,z] + """ + if not value: + self._sensor_instance.irradiance_properties.ClearField("integration_direction") + else: + if self._sensor_template.irradiance_sensor_template.HasField( + "illuminance_type_semi_cylindrical" + ) or self._sensor_template.irradiance_sensor_template.HasField( + "illuminance_type_planar" + ): + self._sensor_instance.irradiance_properties.integration_direction[:] = value + else: + msg = ( + "Integration direction is only settable for sensor template with" + "IlluminanceTypePlanar or IlluminanceTypeSemiCylindrical as illuminance_type." + ) + raise TypeError(msg) + + def set_illuminance_type_planar(self) -> SensorIrradiance: """Set illuminance type planar. Parameters @@ -2463,12 +2507,7 @@ def set_illuminance_type_planar( their signal. """ self._sensor_template.irradiance_sensor_template.illuminance_type_planar.SetInParent() - if not integration_direction: - self._sensor_instance.irradiance_properties.ClearField("integration_direction") - else: - self._sensor_instance.irradiance_properties.integration_direction[:] = ( - integration_direction - ) + self._sensor_instance.irradiance_properties.ClearField("integration_direction") return self def set_illuminance_type_radial(self) -> SensorIrradiance: @@ -2504,49 +2543,37 @@ def set_illuminance_type_cylindrical(self) -> SensorIrradiance: self._sensor_template.irradiance_sensor_template.illuminance_type_cylindrical.SetInParent() return self - def set_illuminance_type_semi_cylindrical( - self, integration_direction: Optional[List[float]] = None - ) -> SensorIrradiance: + def set_illuminance_type_semi_cylindrical(self) -> SensorIrradiance: """Set illuminance type semi cylindrical. - Parameters - ---------- - integration_direction : List[float], optional - Sensor global integration direction [x,y,z]. - By default, ``None``. None means that the Z axis of axis_system is taken. - Returns ------- ansys.speos.core.sensor.SensorIrradiance Irradiance sensor. """ self._sensor_template.irradiance_sensor_template.illuminance_type_semi_cylindrical.SetInParent() - if not integration_direction: - self._sensor_instance.irradiance_properties.ClearField("integration_direction") - else: - self._sensor_instance.irradiance_properties.integration_direction[:] = ( - integration_direction - ) + self._sensor_instance.irradiance_properties.ClearField("integration_direction") return self - def set_axis_system(self, axis_system: Optional[List[float]] = None) -> SensorIrradiance: - """Set position of the sensor. + @property + def axis_system(self) -> List[float]: + """The position of the sensor. + + By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + """ + return self._sensor_instance.irradiance_properties.axis_system + + @axis_system.setter + def axis_system(self, axis_system: List[float]): + """Set the position of the sensor. Parameters ---------- axis_system : Optional[List[float]] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. - - Returns - ------- - ansys.speos.core.sensor.SensorIrradiance - Irradiance sensor. """ - if axis_system is None: - axis_system = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] self._sensor_instance.irradiance_properties.axis_system[:] = axis_system - return self def set_ray_file_type_none(self) -> SensorIrradiance: """Set no ray file generation. @@ -2753,9 +2780,26 @@ def set_layer_type_incidence_angle( ) return self._layer_type - def set_output_face_geometries( - self, geometries: Optional[List[GeoRef]] = None - ) -> SensorIrradiance: + @property + def output_face_geometries(self) -> SensorIrradiance: + """Select output faces for inverse simulation optimization. + + Parameters + ---------- + geometries : List[ansys.speos.core.geo_ref.GeoRef] + List of geometries that will be considered as output faces. + By default, ``[]``, ie no output faces. + + Returns + ------- + ansys.speos.core.sensor.SensorIrradiance + Irradiance sensor. + """ + if self._sensor_instance.irradiance_properties.HasField("output_face_geometries"): + return self._sensor_instance.irradiance_properties.output_face_geometries.geo_paths + + @output_face_geometries.setter + def output_face_geometries(self, geometries: Optional[List[GeoRef]] = None) -> SensorIrradiance: """Select output faces for inverse simulation optimization. Parameters @@ -2772,10 +2816,18 @@ def set_output_face_geometries( if not geometries: self._sensor_instance.irradiance_properties.ClearField("output_face_geometries") else: + geo_paths = [] + for gr in geometries: + if isinstance(gr, GeoRef): + geo_paths.append(gr) + elif isinstance(gr, (face.Face, body.Body, part.Part.SubPart)): + geo_paths.append(gr.geo_path) + else: + msg = f"Type {type(gr)} is not supported as output faces geometry input." + raise TypeError(msg) self._sensor_instance.irradiance_properties.output_face_geometries.geo_paths[:] = [ - gr.to_native_link() for gr in geometries + gp.to_native_link() for gp in geo_paths ] - return self class SensorRadiance(BaseSensor): From dcdb10add0d3863a37b989e203e0c2a97a3ebeaf Mon Sep 17 00:00:00 2001 From: sthoene Date: Wed, 6 Aug 2025 14:34:35 +0200 Subject: [PATCH 06/47] Refactor 3DIrradiance Sensor --- src/ansys/speos/core/generic/constants.py | 6 ++ src/ansys/speos/core/sensor.py | 115 ++++++++++++++++------ 2 files changed, 91 insertions(+), 30 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 0602c01de..f8d688ce7 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -105,3 +105,9 @@ class CAMERASENSOR: """Default width of the camera chip.""" HEIGHT = 5.0 """Default height of the camera chip.""" + + class RADIANCESENSOR: + """Radiance Sensor Constants.""" + + FOCAL_LENGTH = 250 + INTEGRATION_ANGLE = 5 diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 7b42b7ac5..a2f788ef7 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -2799,7 +2799,10 @@ def output_face_geometries(self) -> SensorIrradiance: return self._sensor_instance.irradiance_properties.output_face_geometries.geo_paths @output_face_geometries.setter - def output_face_geometries(self, geometries: Optional[List[GeoRef]] = None) -> SensorIrradiance: + def output_face_geometries( + self, + geometries: Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] = None, + ) -> SensorIrradiance: """Select output faces for inverse simulation optimization. Parameters @@ -2892,7 +2895,9 @@ def __init__( if default_values: # Default values template - self.set_focal().set_integration_angle().set_type_photometric() + self.focal = SENSOR.RADIANCESENSOR.FOCAL_LENGTH + self.integration_angle = SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE + self.set_type_photometric() # Default values properties self.set_axis_system().set_layer_type_none() @@ -3149,7 +3154,21 @@ def set_type_spectral(self) -> BaseSensor.Spectral: ) return self._type - def set_focal(self, value: float = 250) -> SensorRadiance: + @property + def focal(self) -> float: + """The focal value of the Radiance Sensor. + + By default, ``250``. + + Returns + ------- + float + Focal length of the sensor + """ + return self._sensor_template.radiance_sensor_template.focal + + @focal.setter + def focal(self, value: float): """Set the focal value. Parameters @@ -3157,16 +3176,24 @@ def set_focal(self, value: float = 250) -> SensorRadiance: value : float Focal (mm). By default, ``250``. + """ + self._sensor_template.radiance_sensor_template.focal = value + + @property + def integration_angle(self) -> float: + """Set the integration angle. + + By default, ``5``. Returns ------- - ansys.speos.core.sensor.SensorRadiance - Radiance sensor. + float + integration angle of the Radiance Sensor """ - self._sensor_template.radiance_sensor_template.focal = value - return self + return self._sensor_template.radiance_sensor_template.integration_angle - def set_integration_angle(self, value: float = 5) -> SensorRadiance: + @integration_angle.setter + def integration_angle(self, value: float) -> SensorRadiance: """Set the integration angle. Parameters @@ -3174,35 +3201,47 @@ def set_integration_angle(self, value: float = 5) -> SensorRadiance: value : float integration angle (degree) By default, ``5``. - - Returns - ------- - ansys.speos.core.sensor.SensorRadiance - Radiance sensor. """ self._sensor_template.radiance_sensor_template.integration_angle = value - return self - def set_axis_system(self, axis_system: Optional[List[float]] = None) -> SensorRadiance: - """Set position of the sensor. + @property + def axis_system(self) -> List[float]: + """The position of the sensor. + + By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + """ + return self._sensor_instance.radiance_properties.axis_system + + @axis_system.setter + def axis_system(self, axis_system: List[float]): + """Set the position of the sensor. Parameters ---------- axis_system : Optional[List[float]] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + """ + self._sensor_instance.radiance_properties.axis_system[:] = axis_system + + @property + def observer_point(self) -> SensorRadiance: + """Set the position of the observer point. + + This is optional, because the focal length is used by default. + Choosing to set an observer point will make the focal length ignored. + + By default, ``None``. None means that the focal length is used. Returns ------- ansys.speos.core.sensor.SensorRadiance Radiance sensor. """ - if axis_system is None: - axis_system = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] - self._sensor_instance.radiance_properties.axis_system[:] = axis_system - return self + return self._sensor_instance.radiance_properties.observer_point - def set_observer_point(self, value: Optional[List[float]] = None) -> SensorRadiance: + @observer_point.setter + def observer_point(self, value: Optional[List[float]]): """Set the position of the observer point. This is optional, because the focal length is used by default. @@ -3213,17 +3252,11 @@ def set_observer_point(self, value: Optional[List[float]] = None) -> SensorRadia value : List[float], optional Position of the observer point [Ox Oy Oz]. By default, ``None``. None means that the focal length is used. - - Returns - ------- - ansys.speos.core.sensor.SensorRadiance - Radiance sensor. """ if not value: self._sensor_instance.radiance_properties.ClearField("observer_point") else: self._sensor_instance.radiance_properties.observer_point[:] = value - return self def set_layer_type_none(self) -> SensorRadiance: """Define layer separation type as None. @@ -3952,7 +3985,21 @@ def set_layer_type_source(self) -> Sensor3DIrradiance: self._layer_type = None return self - def set_geometries(self, geometries: [List[GeoRef]]) -> Sensor3DIrradiance: + @property + def geometries(self) -> List[str]: + """Geometry faces/bodies to be defined with 3D irradiance sensor. + + Returns + ------- + ansys.speos.core.sensor.Sensor3DIrradiance + 3D Irradiance sensor + """ + return self._sensor_instance.irradiance_3d_properties.geometries.geo_paths + + @geometries.setter + def geometries( + self, geometries: Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] + ) -> Sensor3DIrradiance: """Select geometry faces to be defined with 3D irradiance sensor. Parameters @@ -3965,7 +4012,15 @@ def set_geometries(self, geometries: [List[GeoRef]]) -> Sensor3DIrradiance: ansys.speos.core.sensor.Sensor3DIrradiance 3D Irradiance sensor """ + geo_paths = [] + for gr in geometries: + if isinstance(gr, GeoRef): + geo_paths.append(gr) + elif isinstance(gr, (face.Face, body.Body, part.Part.SubPart)): + geo_paths.append(gr.geo_path) + else: + msg = f"Type {type(gr)} is not supported as 3D Irradiance Sensor geometry input." + raise TypeError(msg) self._sensor_instance.irradiance_3d_properties.geometries.geo_paths[:] = [ - gr.to_native_link() for gr in geometries + gp.to_native_link() for gp in geo_paths ] - return self From 99b09c792f6bdfea1a93715c8313f4c49ef6a3b8 Mon Sep 17 00:00:00 2001 From: sthoene Date: Wed, 6 Aug 2025 15:31:46 +0200 Subject: [PATCH 07/47] unit tests Irradiance Sensor fix minor issues on sensors classes --- src/ansys/speos/core/sensor.py | 4 +- tests/core/test_sensor.py | 281 +++++++++++++++++---------------- 2 files changed, 148 insertions(+), 137 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index a2f788ef7..283b80f15 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -559,7 +559,7 @@ class FaceLayer: def __init__(self, name: str, geometries: List[GeoRef]) -> None: self.name = name """Name of the layer""" - self._geometries = geometries + self.geometries = geometries @property def geometry(self): @@ -797,7 +797,7 @@ def __init__( if default_values: # Default values - self.set_sampling() + self.sampling = SENSOR.LAYERTYPES.INCIDENCE_SAMPLING @property def sampling(self) -> BaseSensor.LayerTypeIncidenceAngle: diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index e9ec5a8c0..85154ea7b 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -27,6 +27,7 @@ from ansys.api.speos.sensor.v1 import camera_sensor_pb2 from ansys.speos.core import Body, GeoRef, Project, Speos, sensor +from ansys.speos.core.generic.constants import ORIGIN, SENSOR from ansys.speos.core.sensor import ( Sensor3DIrradiance, SensorCamera, @@ -44,42 +45,42 @@ def test_create_camera_sensor(speos: Speos): # Default value sensor1 = p.create_sensor(name="Camera.1", feature_type=SensorCamera) assert isinstance(sensor1, SensorCamera) - sensor1.set_mode_photometric().set_mode_color().set_red_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum") + sensor1.set_mode_photometric().set_mode_color().red_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" ) - sensor1.set_mode_photometric().set_mode_color().set_green_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum") + sensor1.set_mode_photometric().set_mode_color().green_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum" ) - sensor1.set_mode_photometric().set_mode_color().set_blue_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum") + sensor1.set_mode_photometric().set_mode_color().blue_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" ) sensor1.commit() assert sensor1.sensor_template_link is not None assert sensor1.sensor_template_link.get().HasField("camera_sensor_template") camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template - assert camera_sensor_template.focal_length == 5.0 - assert camera_sensor_template.imager_distance == 10 + assert camera_sensor_template.focal_length == SENSOR.CAMERASENSOR.FOCAL_LENGTH + assert camera_sensor_template.imager_distance == SENSOR.CAMERASENSOR.IMAGER_DISTANCE assert camera_sensor_template.distortion_file_uri == "" - assert camera_sensor_template.f_number == 20 - assert camera_sensor_template.horz_pixel == 640 - assert camera_sensor_template.vert_pixel == 480 - assert camera_sensor_template.width == 5.0 - assert camera_sensor_template.height == 5.0 + assert camera_sensor_template.f_number == SENSOR.CAMERASENSOR.F_NUMBER + assert camera_sensor_template.horz_pixel == SENSOR.CAMERASENSOR.HORZ_PIXEL + assert camera_sensor_template.vert_pixel == SENSOR.CAMERASENSOR.VERT_PIXEL + assert camera_sensor_template.width == SENSOR.CAMERASENSOR.WIDTH + assert camera_sensor_template.height == SENSOR.CAMERASENSOR.HEIGHT assert camera_sensor_template.HasField("sensor_mode_photometric") mode_photometric = camera_sensor_template.sensor_mode_photometric - assert mode_photometric.acquisition_integration == 0.01 - assert mode_photometric.acquisition_lag_time == 0.0 + assert mode_photometric.acquisition_integration == SENSOR.CAMERASENSOR.ACQUISITION_INTEGRATION + assert mode_photometric.acquisition_lag_time == SENSOR.CAMERASENSOR.ACQUISITION_LAG_TIME assert mode_photometric.transmittance_file_uri == "" assert math.isclose( a=mode_photometric.gamma_correction, - b=2.2, + b=SENSOR.CAMERASENSOR.GAMMA_CORRECTION, rel_tol=1.192092896e-07, ) assert mode_photometric.png_bits == camera_sensor_pb2.EnumSensorCameraPNGBits.PNG_16 assert mode_photometric.HasField("wavelengths_range") - assert mode_photometric.wavelengths_range.w_start == 400 - assert mode_photometric.wavelengths_range.w_end == 700 - assert mode_photometric.wavelengths_range.w_sampling == 13 + assert mode_photometric.wavelengths_range.w_start == SENSOR.WAVELENGTHSRANGE.START + assert mode_photometric.wavelengths_range.w_end == SENSOR.WAVELENGTHSRANGE.END + assert mode_photometric.wavelengths_range.w_sampling == SENSOR.WAVELENGTHSRANGE.SAMPLING assert mode_photometric.HasField("color_mode_color") assert mode_photometric.color_mode_color.red_spectrum_file_uri.endswith( "CameraSensitivityRed.spectrum" @@ -91,69 +92,56 @@ def test_create_camera_sensor(speos: Speos): "CameraSensitivityBlue.spectrum" ) assert mode_photometric.color_mode_color.HasField("balance_mode_none") - assert sensor1._sensor_instance.camera_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] + assert sensor1._sensor_instance.camera_properties.axis_system == ORIGIN assert sensor1._sensor_instance.camera_properties.trajectory_file_uri == "" assert sensor1._sensor_instance.camera_properties.HasField("layer_type_none") # focal_length - sensor1.set_focal_length(value=5.5) + sensor1.focal_length = 5.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.focal_length == 5.5 # imager_distance - sensor1.set_imager_distance(value=10.5) + sensor1.imager_distance = 10.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.imager_distance == 10.5 # f_number - sensor1.set_f_number(value=20.5) + sensor1.f_number = 20.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.f_number == 20.5 # distortion_file_uri - sensor1.set_distortion_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraDistortion_130deg.OPTDistortion") + sensor1.distortion_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraDistortion_130deg.OPTDistortion" ) sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.distortion_file_uri != "" # horz_pixel - sensor1.set_horz_pixel(value=680) + sensor1.horz_pixel = 680 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.horz_pixel == 680 # vert_pixel - sensor1.set_vert_pixel(value=500) + sensor1.vert_pixel = 500 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.vert_pixel == 500 # width - sensor1.set_width(value=5.5) + sensor1.width = 5.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.width == 5.5 # height - sensor1.set_height(value=5.3) + sensor1.height = 5.3 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.height == 5.3 @@ -166,47 +154,48 @@ def test_create_camera_sensor(speos: Speos): # sensor_mode_photometric sensor1.set_mode_photometric() - sensor1.set_mode_photometric().set_mode_color().set_red_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum") + color = sensor1.photometric.set_mode_color() + color.red_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" ) - sensor1.set_mode_photometric().set_mode_color().set_green_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum") + color.green_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum" ) - sensor1.set_mode_photometric().set_mode_color().set_blue_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum") + color.blue_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" ) sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.HasField("sensor_mode_photometric") # acquisition_integration - sensor1.set_mode_photometric().set_acquisition_integration(value=0.03) + sensor1.photometric.acquisition_integration = 0.03 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.acquisition_integration == 0.03 # acquisition_lag_time - sensor1.set_mode_photometric().set_acquisition_lag_time(value=0.1) + sensor1.photometric.acquisition_lag_time = 0.1 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.acquisition_lag_time == 0.1 # transmittance_file_uri - sensor1.set_mode_photometric().set_transmittance_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraTransmittance.spectrum") + sensor1.photometric.transmittance_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraTransmittance.spectrum" ) sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.transmittance_file_uri != "" # gamma_correction - sensor1.set_mode_photometric().set_gamma_correction(value=2.5) + sensor1.photometric.gamma_correction = 2.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.gamma_correction == 2.5 # png_bits - sensor1.set_mode_photometric().set_png_bits_08() + sensor1.photometric.set_png_bits_08() sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert ( @@ -248,18 +237,16 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_monochromatic.spectrum_file_uri != "" # color_mode_color - sensor1.set_mode_photometric().set_mode_color() - # red_spectrum_file_uri - sensor1.set_mode_photometric().set_mode_color().set_red_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum") + sensor1.set_mode_photometric() + color = sensor1.photometric.set_mode_color() + color.red_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" ) - # green_spectrum_file_uri - sensor1.set_mode_photometric().set_mode_color().set_green_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum") + color.green_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum" ) - # blue_spectrum_file_uri - sensor1.set_mode_photometric().set_mode_color().set_blue_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum") + color.blue_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" ) sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template @@ -289,13 +276,25 @@ def test_create_camera_sensor(speos: Speos): camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template mode_photometric = camera_sensor_template.sensor_mode_photometric assert mode_photometric.color_mode_color.HasField("balance_mode_userwhite") - assert mode_photometric.color_mode_color.balance_mode_userwhite.red_gain == 1 - assert mode_photometric.color_mode_color.balance_mode_userwhite.green_gain == 1 - assert mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain == 1 + assert ( + mode_photometric.color_mode_color.balance_mode_userwhite.red_gain + == SENSOR.CAMERASENSOR.GAIN + ) + assert ( + mode_photometric.color_mode_color.balance_mode_userwhite.green_gain + == SENSOR.CAMERASENSOR.GAIN + ) + assert ( + mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain + == SENSOR.CAMERASENSOR.GAIN + ) - sensor1.set_mode_photometric().set_mode_color().set_balance_mode_user_white().set_red_gain( - value=2 - ).set_green_gain(value=3).set_blue_gain(value=4) + balance_mode_user_white = ( + sensor1.set_mode_photometric().set_mode_color().set_balance_mode_user_white() + ) + balance_mode_user_white.red_gain = 2 + balance_mode_user_white.green_gain = 3 + balance_mode_user_white.blue_gain = 4 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template mode_photometric = camera_sensor_template.sensor_mode_photometric @@ -304,12 +303,17 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain == 4 # balance_mode_display - sensor1.set_mode_photometric().set_mode_color().set_balance_mode_display_primaries().set_red_display_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum") - ).set_green_display_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum") - ).set_blue_display_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum") + display_primaries = ( + sensor1.set_mode_photometric().set_mode_color().set_balance_mode_display_primaries() + ) + display_primaries.red_display_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" + ) + display_primaries.green_display_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum" + ) + display_primaries.blue_display_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" ) sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template @@ -333,9 +337,10 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_color.HasField("balance_mode_none") # wavelengths_range - sensor1.set_mode_photometric().set_wavelengths_range().set_start(value=430).set_end( - value=750 - ).set_sampling(value=15) + wavelengths_range = sensor1.photometric.set_wavelengths_range() + wavelengths_range.start = 430 + wavelengths_range.end = 750 + wavelengths_range.sampling = 15 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template mode_photometric = camera_sensor_template.sensor_mode_photometric @@ -346,7 +351,7 @@ def test_create_camera_sensor(speos: Speos): # Properties # axis_system - sensor1.set_axis_system(axis_system=[10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.axis_system = [10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1] sensor1.commit() assert sensor1._sensor_instance.camera_properties.axis_system == [ 10, @@ -376,10 +381,12 @@ def test_create_camera_sensor(speos: Speos): assert sensor1._sensor_instance.camera_properties.HasField("layer_type_none") # test distrotion v1,v2,v3 - sensor1.set_f_number().set_imager_distance().set_focal_length() + sensor1.focal_length = 5.0 + sensor1.imager_distance = 10.0 + sensor1.f_number = 20.0 sensor1.commit() - sensor1.set_distortion_file_uri( - str(Path(test_path) / "CameraInputFiles" / "distortionV{}.OPTDistortion".format(2)) + sensor1.distortion_file_uri = str( + Path(test_path) / "CameraInputFiles" / "distortionV{}.OPTDistortion".format(2) ) camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.f_number == 20.0 @@ -390,10 +397,12 @@ def test_create_camera_sensor(speos: Speos): assert camera_sensor_template.f_number == 0 assert camera_sensor_template.imager_distance == 0 assert camera_sensor_template.focal_length == 0 - sensor1.set_distortion_file_uri( - str(Path(test_path) / "CameraInputFiles" / "distortionV{}.OPTDistortion".format(1)) + sensor1.distortion_file_uri = str( + Path(test_path) / "CameraInputFiles" / "distortionV{}.OPTDistortion".format(1) ) - sensor1.set_f_number().set_imager_distance().set_focal_length() + sensor1.focal_length = 5.0 + sensor1.imager_distance = 10.0 + sensor1.f_number = 20.0 camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.f_number == 0 assert camera_sensor_template.imager_distance == 0 @@ -403,8 +412,8 @@ def test_create_camera_sensor(speos: Speos): assert camera_sensor_template.f_number == 20.0 assert camera_sensor_template.imager_distance == 10.0 assert camera_sensor_template.focal_length == 5.0 - sensor1.set_distortion_file_uri( - str(Path(test_path) / "CameraInputFiles" / "distortionV{}.OPTDistortion".format(4)) + sensor1.distortion_file_uri = str( + Path(test_path) / "CameraInputFiles" / "distortionV{}.OPTDistortion".format(4) ) camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.f_number == 20.0 @@ -448,28 +457,15 @@ def test_create_irradiance_sensor(speos: Speos): assert sensor_template.HasField("sensor_type_photometric") assert sensor_template.HasField("illuminance_type_planar") assert sensor_template.HasField("dimensions") - assert sensor_template.dimensions.x_start == -50.0 - assert sensor_template.dimensions.x_end == 50.0 - assert sensor_template.dimensions.x_sampling == 100 - assert sensor_template.dimensions.y_start == -50.0 - assert sensor_template.dimensions.y_end == 50.0 - assert sensor_template.dimensions.y_sampling == 100 + assert sensor_template.dimensions.x_start == SENSOR.DIMENSIONS.X_START + assert sensor_template.dimensions.x_end == SENSOR.DIMENSIONS.X_END + assert sensor_template.dimensions.x_sampling == SENSOR.DIMENSIONS.X_SAMPLING + assert sensor_template.dimensions.y_start == SENSOR.DIMENSIONS.Y_START + assert sensor_template.dimensions.y_end == SENSOR.DIMENSIONS.Y_END + assert sensor_template.dimensions.y_sampling == SENSOR.DIMENSIONS.Y_SAMPLING assert sensor1._sensor_instance.HasField("irradiance_properties") irra_properties = sensor1._sensor_instance.irradiance_properties - assert irra_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] + assert irra_properties.axis_system == ORIGIN assert irra_properties.HasField("layer_type_none") assert irra_properties.ray_file_type == sensor1._sensor_instance.EnumRayFileType.RayFileNone assert irra_properties.integration_direction == [] @@ -481,13 +477,23 @@ def test_create_irradiance_sensor(speos: Speos): sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.HasField("sensor_type_colorimetric") assert sensor_template.sensor_type_colorimetric.HasField("wavelengths_range") - assert sensor_template.sensor_type_colorimetric.wavelengths_range.w_start == 400 - assert sensor_template.sensor_type_colorimetric.wavelengths_range.w_end == 700 - assert sensor_template.sensor_type_colorimetric.wavelengths_range.w_sampling == 13 + assert ( + sensor_template.sensor_type_colorimetric.wavelengths_range.w_start + == SENSOR.WAVELENGTHSRANGE.START + ) + assert ( + sensor_template.sensor_type_colorimetric.wavelengths_range.w_end + == SENSOR.WAVELENGTHSRANGE.END + ) + assert ( + sensor_template.sensor_type_colorimetric.wavelengths_range.w_sampling + == SENSOR.WAVELENGTHSRANGE.SAMPLING + ) # chosen wavelengths range - sensor1.set_type_colorimetric().set_wavelengths_range().set_start(value=450).set_end( - value=800 - ).set_sampling(value=15) + wavelengths_range = sensor1.set_type_colorimetric().set_wavelengths_range() + wavelengths_range.start = 450 + wavelengths_range.end = 800 + wavelengths_range.sampling = 15 sensor1.commit() sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.sensor_type_colorimetric.wavelengths_range.w_start == 450 @@ -511,9 +517,10 @@ def test_create_irradiance_sensor(speos: Speos): assert sensor_template.sensor_type_spectral.wavelengths_range.w_end == 700 assert sensor_template.sensor_type_spectral.wavelengths_range.w_sampling == 13 # chosen wavelengths range - sensor1.set_type_spectral().set_wavelengths_range().set_start(value=450).set_end( - value=800 - ).set_sampling(value=15) + wavelengths_range = sensor1.set_type_spectral().set_wavelengths_range() + wavelengths_range.start = 450 + wavelengths_range.end = 800 + wavelengths_range.sampling = 15 sensor1.commit() sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.sensor_type_spectral.wavelengths_range.w_start == 450 @@ -551,18 +558,22 @@ def test_create_irradiance_sensor(speos: Speos): # assert sensor_template.HasField("illuminance_type_semi_cylindrical") # illuminance_type_planar - sensor1.set_illuminance_type_planar(integration_direction=[0, 0, -1]) + sensor1.set_illuminance_type_planar() + sensor1.integration_direction = [0, 0, -1] sensor1.commit() sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.HasField("illuminance_type_planar") - sensor1.set_illuminance_type_planar(integration_direction=None) # cancel integration direction + sensor1.integration_direction = None # cancel integration direction assert irra_properties.integration_direction == [] # dimensions - sensor1.set_dimensions().set_x_start(value=-10).set_x_end(value=10).set_x_sampling( - value=60 - ).set_y_start(value=-20).set_y_end(value=20).set_y_sampling(value=120) + sensor1.dimensions.x_start = -10 + sensor1.dimensions.x_end = 10 + sensor1.dimensions.x_sampling = 60 + sensor1.dimensions.y_start = -20 + sensor1.dimensions.y_end = 20 + sensor1.dimensions.y_sampling = 120 sensor1.commit() sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.HasField("dimensions") @@ -575,7 +586,7 @@ def test_create_irradiance_sensor(speos: Speos): # properties # axis_system - sensor1.set_axis_system([10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.axis_system = [10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1] sensor1.commit() assert irra_properties.axis_system == [ 10, @@ -625,7 +636,9 @@ def test_create_irradiance_sensor(speos: Speos): assert irra_properties.HasField("layer_type_source") # layer_type_face - sensor1.set_layer_type_face().set_sca_filtering_mode_intersected_one_time().set_layers( + layer_face = sensor1.set_layer_type_face() + layer_face.set_sca_filtering_mode_intersected_one_time() + layer_face.set_layers( values=[ sensor.BaseSensor.FaceLayer( name="Layer.1", geometries=[GeoRef.from_native_link("TheBodyB")] @@ -654,7 +667,7 @@ def test_create_irradiance_sensor(speos: Speos): "TheBodyC/TheFaceC2", ] - sensor1.set_layer_type_face().set_sca_filtering_mode_last_impact() + layer_face.set_sca_filtering_mode_last_impact() sensor1.commit() assert ( irra_properties.layer_type_face.sca_filtering_mode @@ -662,9 +675,9 @@ def test_create_irradiance_sensor(speos: Speos): ) # layer_type_sequence - sensor1.set_layer_type_sequence().set_maximum_nb_of_sequence( - value=5 - ).set_define_sequence_per_faces() + layer_by_sequence = sensor1.set_layer_type_sequence() + layer_by_sequence.maximum_nb_of_sequence = 5 + layer_by_sequence.set_define_sequence_per_faces() sensor1.commit() assert irra_properties.HasField("layer_type_sequence") assert irra_properties.layer_type_sequence.maximum_nb_of_sequence == 5 @@ -687,7 +700,7 @@ def test_create_irradiance_sensor(speos: Speos): assert irra_properties.HasField("layer_type_polarization") # layer_type_incidence_angle - sensor1.set_layer_type_incidence_angle().set_sampling(value=8) + sensor1.set_layer_type_incidence_angle().sampling = 8 sensor1.commit() assert irra_properties.HasField("layer_type_incidence_angle") assert irra_properties.layer_type_incidence_angle.sampling == 8 @@ -698,12 +711,10 @@ def test_create_irradiance_sensor(speos: Speos): assert irra_properties.HasField("layer_type_none") # output_face_geometries - sensor1.set_output_face_geometries( - geometries=[ - GeoRef.from_native_link(geopath="TheBodyB/TheFaceB1"), - GeoRef.from_native_link(geopath="TheBodyB/TheFaceB2"), - ] - ) + sensor1.output_face_geometries = [ + GeoRef.from_native_link(geopath="TheBodyB/TheFaceB1"), + GeoRef.from_native_link(geopath="TheBodyB/TheFaceB2"), + ] assert irra_properties.output_face_geometries.geo_paths == [ "TheBodyB/TheFaceB1", "TheBodyB/TheFaceB2", From 8aabb489584bb96d942b4eb17e1344f05f344b06 Mon Sep 17 00:00:00 2001 From: sthoene Date: Wed, 6 Aug 2025 15:41:43 +0200 Subject: [PATCH 08/47] unit tests radiance Sensor minor fix on radiance class --- src/ansys/speos/core/sensor.py | 3 +- tests/core/test_sensor.py | 92 ++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 283b80f15..751458dda 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -2899,7 +2899,8 @@ def __init__( self.integration_angle = SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE self.set_type_photometric() # Default values properties - self.set_axis_system().set_layer_type_none() + self.axis_system = ORIGIN + self.set_layer_type_none() @property def visual_data(self) -> _VisualData: diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index 85154ea7b..cd7138277 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -751,31 +751,42 @@ def test_create_radiance_sensor(speos: Speos): assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField( "sensor_type_photometric" ) - assert sensor1.sensor_template_link.get().radiance_sensor_template.focal == 250 - assert sensor1.sensor_template_link.get().radiance_sensor_template.integration_angle == 5 + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.focal + == SENSOR.RADIANCESENSOR.FOCAL_LENGTH + ) + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.integration_angle + == SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE + ) assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField("dimensions") - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_start == -50.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_end == 50.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_sampling == 100 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_start == -50.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_end == 50.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_sampling == 100 + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_start + == SENSOR.DIMENSIONS.X_START + ) + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_end + == SENSOR.DIMENSIONS.X_END + ) + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_sampling + == SENSOR.DIMENSIONS.X_SAMPLING + ) + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_start + == SENSOR.DIMENSIONS.Y_START + ) + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_end + == SENSOR.DIMENSIONS.Y_END + ) + assert ( + sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_sampling + == SENSOR.DIMENSIONS.Y_SAMPLING + ) assert sensor1._sensor_instance.HasField("radiance_properties") radiance_properties = sensor1._sensor_instance.radiance_properties - assert radiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] + assert radiance_properties.axis_system == ORIGIN assert radiance_properties.HasField("layer_type_none") assert radiance_properties.observer_point == [] @@ -800,20 +811,21 @@ def test_create_radiance_sensor(speos: Speos): ) assert ( sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start - == 400 + == SENSOR.WAVELENGTHSRANGE.START ) assert ( sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_end - == 700 + == SENSOR.WAVELENGTHSRANGE.END ) assert ( sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_sampling - == 13 + == SENSOR.WAVELENGTHSRANGE.SAMPLING ) # chosen wavelengths range - sensor1.set_type_spectral().set_wavelengths_range().set_start(value=450).set_end( - value=800 - ).set_sampling(value=15) + wavelengths_range = sensor1.set_type_spectral().set_wavelengths_range() + wavelengths_range.start = 450 + wavelengths_range.end = 800 + wavelengths_range.sampling = 15 sensor1.commit() assert ( sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start @@ -836,19 +848,22 @@ def test_create_radiance_sensor(speos: Speos): ) # focal - sensor1.set_focal(value=150.5) + sensor1.focal = 150.5 sensor1.commit() assert sensor1.sensor_template_link.get().radiance_sensor_template.focal == 150.5 # integration_angle - sensor1.set_integration_angle(value=4.5) + sensor1.integration_angle = 4.5 sensor1.commit() assert sensor1.sensor_template_link.get().radiance_sensor_template.integration_angle == 4.5 # dimensions - sensor1.set_dimensions().set_x_start(value=-10).set_x_end(value=10).set_x_sampling( - value=60 - ).set_y_start(value=-20).set_y_end(value=20).set_y_sampling(value=120) + sensor1.dimensions.x_start = -10 + sensor1.dimensions.x_end = 10 + sensor1.dimensions.x_sampling = 60 + sensor1.dimensions.y_start = -20 + sensor1.dimensions.y_end = 20 + sensor1.dimensions.y_sampling = 120 sensor1.commit() assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField("dimensions") assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_start == -10.0 @@ -860,7 +875,7 @@ def test_create_radiance_sensor(speos: Speos): # properties # axis_system - sensor1.set_axis_system([10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.axis_system = [10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1] sensor1.commit() assert radiance_properties.axis_system == [ 10, @@ -878,7 +893,7 @@ def test_create_radiance_sensor(speos: Speos): ] # observer_point - sensor1.set_observer_point([20, 30, 50]) + sensor1.observer_point = [20, 30, 50] sensor1.commit() assert radiance_properties.observer_point == [ 20, @@ -886,7 +901,7 @@ def test_create_radiance_sensor(speos: Speos): 50, ] - sensor1.set_observer_point(value=None) # cancel observer point chosen previously + sensor1.observer_point = None # cancel observer point chosen previously sensor1.commit() assert radiance_properties.observer_point == [] @@ -934,9 +949,8 @@ def test_create_radiance_sensor(speos: Speos): ) # layer_type_sequence - sensor1.set_layer_type_sequence().set_maximum_nb_of_sequence( - value=5 - ).set_define_sequence_per_faces() + sensor1.set_layer_type_sequence().maximum_nb_of_sequence = 5 + sensor1.set_layer_type_sequence().set_define_sequence_per_faces() sensor1.commit() assert radiance_properties.HasField("layer_type_sequence") assert radiance_properties.layer_type_sequence.maximum_nb_of_sequence == 5 From b73e0aa5479c103d17820b12832213e51e748837 Mon Sep 17 00:00:00 2001 From: sthoene Date: Wed, 6 Aug 2025 15:57:15 +0200 Subject: [PATCH 09/47] Finalize unit test --- tests/core/test_sensor.py | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index cd7138277..0c10b70c1 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -990,7 +990,7 @@ def test_create_3d_irradiance_sensor(speos: Speos): ) body = p.find(name="PrismBody", name_regex=True, feature_type=Body)[0] sensor_3d = p.create_sensor(name="3d", feature_type=Sensor3DIrradiance) - sensor_3d.set_geometries([body.geo_path]) + sensor_3d.geometries = [body.geo_path] sensor_3d.commit() # when creating 3D irradiance, default properties: @@ -1078,7 +1078,8 @@ def test_create_3d_irradiance_sensor(speos: Speos): colorimetric_info = sensor_3d.sensor_template_link.get().irradiance_3d.type_colorimetric assert colorimetric_info.wavelength_start == 400 assert colorimetric_info.wavelength_end == 700 - sensor_3d.set_type_colorimetric().set_wavelengths_range().set_start(500) + wavelengths_range = sensor_3d.set_type_colorimetric().set_wavelengths_range() + wavelengths_range.start = 500 sensor_3d.commit() colorimetric_info = sensor_3d.sensor_template_link.get().irradiance_3d.type_colorimetric assert sensor_3d.get(key="wavelength_start") == 500 @@ -1138,7 +1139,7 @@ def test_commit_sensor(speos: Speos): assert p.scene_link.get().sensors[0] == sensor1._sensor_instance # Change only in local not committed - sensor1.set_axis_system([10, 10, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.axis_system = [10, 10, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert p.scene_link.get().sensors[0] != sensor1._sensor_instance sensor1.delete() @@ -1184,8 +1185,8 @@ def test_reset_sensor(speos: Speos): 1, ] # server - sensor1.set_dimensions().set_x_start(0) - sensor1.set_axis_system([1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.dimensions.x_start = 0 + sensor1.axis_system = [1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == 0 # local assert ( sensor1.sensor_template_link.get().irradiance_sensor_template.dimensions.x_start == -50 @@ -1281,14 +1282,14 @@ def test_irradiance_modify_after_reset(speos: Speos): sensor1._sensor_template.irradiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start == 400 ) - sensor1.set_type_spectral().set_wavelengths_range().set_start(value=500) + sensor1.set_type_spectral().set_wavelengths_range().start = 500 assert ( sensor1._sensor_template.irradiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start == 500 ) # Intermediate class for dimensions assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == -50 - sensor1.set_dimensions().set_x_start(-100) + sensor1.set_dimensions().x_start = -100 assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == -100 # Props @@ -1306,7 +1307,7 @@ def test_irradiance_modify_after_reset(speos: Speos): 0, 1, ] - sensor1.set_axis_system([50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.axis_system = [50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_instance.irradiance_properties.axis_system == [ 50, 20, @@ -1326,7 +1327,7 @@ def test_irradiance_modify_after_reset(speos: Speos): sensor1._sensor_instance.irradiance_properties.layer_type_sequence.maximum_nb_of_sequence == 10 ) - sensor1.set_layer_type_sequence().set_maximum_nb_of_sequence(value=15) + sensor1.set_layer_type_sequence().maximum_nb_of_sequence = 15 assert ( sensor1._sensor_instance.irradiance_properties.layer_type_sequence.maximum_nb_of_sequence == 15 @@ -1352,21 +1353,21 @@ def test_radiance_modify_after_reset(speos: Speos): # Modify after a reset # Template assert sensor1._sensor_template.radiance_sensor_template.focal == 250 - sensor1.set_focal(value=100) + sensor1.focal = 100 assert sensor1._sensor_template.radiance_sensor_template.focal == 100 # Intermediate class for type : colorimetric assert ( sensor1._sensor_template.radiance_sensor_template.sensor_type_colorimetric.wavelengths_range.w_start == 400 ) - sensor1.set_type_colorimetric().set_wavelengths_range().set_start(value=500) + sensor1.set_type_colorimetric().set_wavelengths_range().start = 500 assert ( sensor1._sensor_template.radiance_sensor_template.sensor_type_colorimetric.wavelengths_range.w_start == 500 ) # Intermediate class for dimensions assert sensor1._sensor_template.radiance_sensor_template.dimensions.x_start == -50 - sensor1.set_dimensions().set_x_start(-100) + sensor1.set_dimensions().x_start = -100 assert sensor1._sensor_template.radiance_sensor_template.dimensions.x_start == -100 ## Props @@ -1384,7 +1385,7 @@ def test_radiance_modify_after_reset(speos: Speos): 0, 1, ] - sensor1.set_axis_system([50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.axis_system = [50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_instance.radiance_properties.axis_system == [ 50, 20, @@ -1404,7 +1405,7 @@ def test_radiance_modify_after_reset(speos: Speos): sensor1._sensor_instance.radiance_properties.layer_type_sequence.maximum_nb_of_sequence == 10 ) - sensor1.set_layer_type_sequence().set_maximum_nb_of_sequence(value=15) + sensor1.set_layer_type_sequence().maximum_nb_of_sequence = 15 assert ( sensor1._sensor_instance.radiance_properties.layer_type_sequence.maximum_nb_of_sequence == 15 @@ -1420,15 +1421,16 @@ def test_camera_modify_after_reset(speos: Speos): # Create + commit sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorCamera) assert isinstance(sensor1, SensorCamera) - sensor1.set_mode_photometric().set_mode_color().set_balance_mode_user_white() - sensor1.set_mode_photometric().set_mode_color().set_red_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum") + color = sensor1.set_mode_photometric().set_mode_color() + white_mode = color.set_balance_mode_user_white() + color.red_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" ) - sensor1.set_mode_photometric().set_mode_color().set_green_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum") + color.green_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum" ) - sensor1.set_mode_photometric().set_mode_color().set_blue_spectrum_file_uri( - uri=str(Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum") + color.blue_spectrum_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" ) sensor1.set_mode_photometric().set_layer_type_source() sensor1.commit() @@ -1439,14 +1441,14 @@ def test_camera_modify_after_reset(speos: Speos): # Modify after a reset # Template assert sensor1._sensor_template.camera_sensor_template.focal_length == 5 - sensor1.set_focal_length(value=40) + sensor1.focal_length = 40 assert sensor1._sensor_template.camera_sensor_template.focal_length == 40 # Intermediate class for mode : photometric + wavelengths assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_start == 400 ) - sensor1.set_mode_photometric().set_wavelengths_range().set_start(value=500) + sensor1.set_mode_photometric().set_wavelengths_range().start = 500 assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_start == 500 @@ -1456,9 +1458,7 @@ def test_camera_modify_after_reset(speos: Speos): sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain == 1 ) - sensor1.set_mode_photometric().set_mode_color().set_balance_mode_user_white().set_blue_gain( - value=0.5 - ) + white_mode.blue_gain = 0.5 assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain == 0.5 @@ -1479,7 +1479,7 @@ def test_camera_modify_after_reset(speos: Speos): 0, 1, ] - sensor1.set_axis_system([50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + sensor1.axis_system = [50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_instance.camera_properties.axis_system == [ 50, 20, From 03bf5378818b5c3141c1514bfa6179cac6c3a528 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Wed, 6 Aug 2025 13:59:53 +0000 Subject: [PATCH 10/47] chore: adding changelog file 691.miscellaneous.md [dependabot-skip] --- doc/changelog.d/691.miscellaneous.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/691.miscellaneous.md diff --git a/doc/changelog.d/691.miscellaneous.md b/doc/changelog.d/691.miscellaneous.md new file mode 100644 index 000000000..696fd0c0a --- /dev/null +++ b/doc/changelog.d/691.miscellaneous.md @@ -0,0 +1 @@ +Sensor \ No newline at end of file From 84e0361dc32d8505617b9e81600254af3e617cd3 Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 7 Aug 2025 08:12:43 +0200 Subject: [PATCH 11/47] fix project tests --- tests/core/test_project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/test_project.py b/tests/core/test_project.py index 555950a0d..5bd37b8c2 100644 --- a/tests/core/test_project.py +++ b/tests/core/test_project.py @@ -355,7 +355,7 @@ def test_from_file(speos: Speos): assert type(feat_ssrs[0]) is SensorIrradiance # And that we can modify it (and that other values are not overridden by default values) - feat_ssrs[0].set_type_colorimetric().set_wavelengths_range().set_end(value=800) + feat_ssrs[0].set_type_colorimetric().set_wavelengths_range().end = 800 feat_ssrs[0].commit() ssr_link = speos.client[p.scene_link.get().sensors[0].sensor_guid] ssr_data = ssr_link.get() @@ -522,7 +522,7 @@ def test_preview_visual_data(speos: Speos): p5 = Project(speos=speos, path=str(Path(test_path) / "Prism.speos" / "Prism.speos")) ssr_3d = p5.create_sensor(name="Sensor3D", feature_type=Sensor3DIrradiance) body = p5.find(name="PrismBody", name_regex=True, feature_type=Body)[0] - ssr_3d.set_geometries([body.geo_path]) + ssr_3d.geometries = [body.geo_path] ssr_3d.commit() p5.preview() # test loading 3d irradiance sensor From 77a2e2d561d3e39641a85f151317fd55bef0f9a6 Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 7 Aug 2025 11:09:57 +0200 Subject: [PATCH 12/47] fix sensor tests --- tests/core/test_sensor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index 0c10b70c1..bb03ed7ca 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -1422,7 +1422,6 @@ def test_camera_modify_after_reset(speos: Speos): sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorCamera) assert isinstance(sensor1, SensorCamera) color = sensor1.set_mode_photometric().set_mode_color() - white_mode = color.set_balance_mode_user_white() color.red_spectrum_file_uri = str( Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" ) @@ -1458,6 +1457,8 @@ def test_camera_modify_after_reset(speos: Speos): sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain == 1 ) + color = sensor1.set_mode_photometric().set_mode_color() + white_mode = color.set_balance_mode_user_white() white_mode.blue_gain = 0.5 assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain From 63cbe830fd7ef6a320eaff71b38ecce0995647ae Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 7 Aug 2025 12:00:12 +0200 Subject: [PATCH 13/47] fix examples and change cheat sheet --- doc/source/cheat_sheet/cheat_sheet_script.qmd | 19 ++++---- examples/core/prism-example.py | 7 ++- examples/core/sensor.py | 43 +++++++++++-------- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/doc/source/cheat_sheet/cheat_sheet_script.qmd b/doc/source/cheat_sheet/cheat_sheet_script.qmd index aec202615..f7e268ec9 100644 --- a/doc/source/cheat_sheet/cheat_sheet_script.qmd +++ b/doc/source/cheat_sheet/cheat_sheet_script.qmd @@ -212,13 +212,18 @@ from ansys.speos.core.sensor import SensorRadiance r_sensor = project.create_sensor(name='Radiance.1', feature_type=SensorRadiance) # define size dim = r_sensor.set_dimensions() -dim.set_x_start(-5).set_x_end(5).set_x_sampling(10) -dim.set_y_start(-5).set_y_end(5).set_y_sampling(10) +dim.x_start = -5 +dim.x_end = 5 +dim.x_sampling = 10 +dim.y_start = -5 +dim.y_end = 5 +dim.y_sampling = 10 # define type and Wavelength range col = r_sensor.set_type_colorimetric() wl = col.set_wavelengths_range() -wl.set_start(380).set_end(780) -wl.set_sampling(50) +wl.start = 380 +wl.end = 780 +wl.sampling = 50 # define Layer separation r_sensor.set_layer_type_source() r_sensor.commit() @@ -246,12 +251,10 @@ c_sensor.set_distortion_file_uri( 'distortion_file_path') # Choose photometric mode photo_cam = c_sensor.set_mode_photometric() -photo_cam.set_transmittance_file_uri( - 'transmittance_file_path') +photo_cam.transmittance_file_uri = 'transmittance_file_path' # Choose color mode c_mode = photo_cam.set_mode_color() -c_mode.set_blue_spectrum_file_uri( - 'blue_spectrum_path') +c_mode.blue_spectrum_file_uri = 'blue_spectrum_path' # same method for red and green spectrum c_sensor.commit() ``` diff --git a/examples/core/prism-example.py b/examples/core/prism-example.py index 081b03420..7f01d2597 100644 --- a/examples/core/prism-example.py +++ b/examples/core/prism-example.py @@ -93,14 +93,17 @@ irr_features = p.find(name=".*", name_regex=True, feature_type=SensorIrradiance) irr = irr_features[0] -irr.set_type_spectral().set_wavelengths_range().set_start(500).set_end(600).set_sampling(11) +wl = irr.set_type_spectral().set_wavelengths_range() +wl.start = 500 +wl.end = 600 +wl.sampling = 11 irr.commit() # Create and add a new sensor, e.g. 3d irradiance sensor body = p.find(name="PrismBody", name_regex=True, feature_type=Body)[0] sensor_3d = p.create_sensor(name="3d_irradiance", feature_type=Sensor3DIrradiance) -sensor_3d.set_geometries([body.geo_path]) +sensor_3d.geometries = [body.geo_path] sensor_3d.commit() sim.set_sensor_paths(["Irradiance.1:564", "3d_irradiance"]) sim.commit() diff --git a/examples/core/sensor.py b/examples/core/sensor.py index 910d22efd..8e73afa50 100644 --- a/examples/core/sensor.py +++ b/examples/core/sensor.py @@ -99,13 +99,14 @@ def create_face(body): red_spectrum_path = str(assets_data_path / FILES / "CameraSensitivityRed.spectrum") sensor1 = p.create_sensor(name="Camera.1", feature_type=SensorCamera) -sensor1.set_distortion_file_uri(uri=distortion_file_path) +sensor1.distortion_file_uri = distortion_file_path # Choose photometric mode -sensor1.set_mode_photometric().set_transmittance_file_uri(uri=transmittance_file_path) +sensor1.set_mode_photometric().transmittance_file_uri = transmittance_file_path # Choose color mode (will imply to give spectrum file for blue, green and red) -sensor1.set_mode_photometric().set_mode_color().set_blue_spectrum_file_uri(uri=blue_spectrum_path) -sensor1.set_mode_photometric().set_mode_color().set_green_spectrum_file_uri(uri=green_spectrum_path) -sensor1.set_mode_photometric().set_mode_color().set_red_spectrum_file_uri(uri=red_spectrum_path) +mode_color = sensor1.photometric.set_mode_color() +mode_color.blue_spectrum_file_uri = blue_spectrum_path +mode_color.green_spectrum_file_uri = green_spectrum_path +mode_color.red_spectrum_file_uri = red_spectrum_path print(sensor1) # - @@ -134,17 +135,19 @@ def create_face(body): red_spectrum_path = str(assets_data_path / FILES / "CameraSensitivityRed.spectrum") sensor2 = p.create_sensor(name="Camera.2", feature_type=SensorCamera) -sensor2.set_distortion_file_uri(uri=distortion_file_path) -sensor2.set_mode_photometric().set_transmittance_file_uri(uri=transmittance_file_path) -sensor2.set_mode_photometric().set_layer_type_source() -sensor2.set_mode_photometric().set_mode_color().set_blue_spectrum_file_uri(uri=blue_spectrum_path) -sensor2.set_mode_photometric().set_mode_color().set_green_spectrum_file_uri(uri=green_spectrum_path) -sensor2.set_mode_photometric().set_mode_color().set_red_spectrum_file_uri(uri=red_spectrum_path) -sensor2.set_focal_length(5.5) -sensor2.set_height(value=6).set_width(value=6) # dimensions -sensor2.set_axis_system( - [20, 10, 40, 1, 0, 0, 0, 1, 0, 0, 0, 1] -) # camera location [Origin, Xvector, Yvector, Zvector] +sensor2.distortion_file_uri = distortion_file_path +photometric = sensor2.set_mode_photometric() +photometric.transmittance_file_uri(uri=transmittance_file_path) +photometric.set_layer_type_source() +color = photometric.set_mode_color() +color.blue_spectrum_file_uri = blue_spectrum_path +color.green_spectrum_file_uri = green_spectrum_path +color.red_spectrum_file_uri = red_spectrum_path +sensor2.focal_length = 5.5 +sensor2.height = 6 +sensor2.width = 6 # dimensions +sensor2.axis_system = [20, 10, 40, 1, 0, 0, 0, 1, 0, 0, 0, 1] +# camera location [Origin, Xvector, Yvector, Zvector] sensor2.commit() print(sensor2) @@ -172,7 +175,8 @@ def create_face(body): # If you don't, you will still only watch what is committed on the server. # modify f number and axis system -sensor1.set_f_number(value=11).set_axis_system([17, 10, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1]) +sensor1.f_number = 11 +sensor1.axis_system = [17, 10, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] sensor1.commit() print(sensor1) @@ -217,7 +221,8 @@ def create_face(body): sensor4.commit() print(sensor4) -sensor4.set_focal(value=200).set_type_spectral() +sensor4.focal = 200 +sensor4.set_type_spectral() sensor4.set_layer_type_source() sensor4.commit() print(sensor4) @@ -229,7 +234,7 @@ def create_face(body): create_helper_geometries(p) sensor5 = p.create_sensor(name="3D_Irradiance.2", feature_type=Sensor3DIrradiance) -sensor5.set_geometries([GeoRef.from_native_link("TheBodyB/TheFaceF")]) +sensor5.geometries = [GeoRef.from_native_link("TheBodyB/TheFaceF")] sensor5.commit() print(sensor5) From 54a674114cf78010789ab7b5d02d36d34535176e Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 7 Aug 2025 12:10:27 +0200 Subject: [PATCH 14/47] fix examples and change cheat sheet --- tests/core/test_sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index bb03ed7ca..65706c8e3 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -1422,6 +1422,7 @@ def test_camera_modify_after_reset(speos: Speos): sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorCamera) assert isinstance(sensor1, SensorCamera) color = sensor1.set_mode_photometric().set_mode_color() + white_mode = color.set_balance_mode_user_white() color.red_spectrum_file_uri = str( Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" ) From 52c744341fdab35d07e8fdc51e4fe5410732340b Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 7 Aug 2025 12:12:47 +0200 Subject: [PATCH 15/47] unit test fix --- tests/core/test_sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index 65706c8e3..8b4d9b51b 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -1422,7 +1422,7 @@ def test_camera_modify_after_reset(speos: Speos): sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorCamera) assert isinstance(sensor1, SensorCamera) color = sensor1.set_mode_photometric().set_mode_color() - white_mode = color.set_balance_mode_user_white() + color.set_balance_mode_user_white() color.red_spectrum_file_uri = str( Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" ) From b61aada3e204503f98863cc3b6306ec5cbb9ee99 Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 7 Aug 2025 15:52:11 +0200 Subject: [PATCH 16/47] unit test fix --- tests/core/test_simulation.py | 42 ++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/tests/core/test_simulation.py b/tests/core/test_simulation.py index e8122a744..6603c6b40 100644 --- a/tests/core/test_simulation.py +++ b/tests/core/test_simulation.py @@ -383,11 +383,11 @@ def test_commit(speos: Speos): opt_prop.commit() ssr = p.create_sensor(name="Irradiance.1", feature_type=SensorIrradiance) - ssr.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + ssr.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] ssr.commit() ssr2 = p.create_sensor(name="Irradiance.2", feature_type=SensorIrradiance) - ssr2.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + ssr2.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] ssr2.commit() src = p.create_source(name="Luminaire.1", feature_type=SourceLuminaire) @@ -437,11 +437,11 @@ def test_reset(speos: Speos): opt_prop.commit() ssr = p.create_sensor(name="Irradiance.1", feature_type=SensorIrradiance) - ssr.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + ssr.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] ssr.commit() ssr2 = p.create_sensor(name="Irradiance.2", feature_type=SensorIrradiance) - ssr2.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + ssr2.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] ssr2.commit() src = p.create_source(name="Luminaire.1", feature_type=SourceLuminaire) @@ -491,11 +491,11 @@ def test_direct_modify_after_reset(speos: Speos): opt_prop.commit() ssr = p.create_sensor(name="Irradiance.1", feature_type=SensorIrradiance) - ssr.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + ssr.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] ssr.commit() ssr2 = p.create_sensor(name="Irradiance.2", feature_type=SensorIrradiance) - ssr2.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + ssr2.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] ssr2.commit() src = p.create_source(name="Luminaire.1", feature_type=SourceLuminaire) @@ -561,11 +561,13 @@ def test_inverse_modify_after_reset(speos: Speos): opt_prop.commit() ssr = p.create_sensor(name="Irradiance.1", feature_type=SensorIrradiance) - ssr.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]).set_type_colorimetric() + ssr.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] + ssr.set_type_colorimetric() ssr.commit() ssr2 = p.create_sensor(name="Irradiance.2", feature_type=SensorIrradiance) - ssr2.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]).set_type_colorimetric() + ssr2.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] + ssr2.set_type_colorimetric() ssr2.commit() src = p.create_source(name="Luminaire.1", feature_type=SourceLuminaire) @@ -637,11 +639,13 @@ def test_interactive_modify_after_reset(speos: Speos): opt_prop.commit() ssr = p.create_sensor(name="Irradiance.1", feature_type=SensorIrradiance) - ssr.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]).set_type_colorimetric() + ssr.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] + ssr.set_type_colorimetric() ssr.commit() ssr2 = p.create_sensor(name="Irradiance.2", feature_type=SensorIrradiance) - ssr2.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]).set_type_colorimetric() + ssr2.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] + ssr2.set_type_colorimetric() ssr2.commit() src = p.create_source(name="Luminaire.1", feature_type=SourceLuminaire) @@ -693,7 +697,7 @@ def test_delete(speos: Speos): opt_prop.commit() ssr = p.create_sensor(name="Irradiance.1", feature_type=SensorIrradiance) - ssr.set_axis_system(axis_system=[0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + ssr.axis_system = [0, 0, -20, 1, 0, 0, 0, 1, 0, 0, 0, 1] ssr.commit() src = p.create_source(name="Luminaire.1", feature_type=SourceLuminaire) @@ -1032,7 +1036,9 @@ def test_export_vtp(speos: Speos): ) sim = p5.find(name=".*", name_regex=True, feature_type=SimulationDirect)[0] sensor_irra = p5.find(name=".*", name_regex=True, feature_type=SensorIrradiance)[0] - sensor_irra.set_dimensions().set_x_sampling(10).set_y_sampling(10) + dim = sensor_irra.set_dimensions() + dim.x_sampling = 10 + dim.y_sampling = 10 sensor_irra.set_type_photometric() sensor_irra.commit() speos_results, vtp_results = sim.compute_CPU(export_vtp=True) @@ -1085,7 +1091,9 @@ def test_export_vtp(speos: Speos): ) sim = p6.find(name=".*", name_regex=True, feature_type=SimulationDirect)[0] sensor_irra = p6.find(name=".*", name_regex=True, feature_type=SensorIrradiance)[0] - sensor_irra.set_dimensions().set_x_sampling(10).set_y_sampling(10) + dim = sensor_irra.set_dimensions() + dim.x_sampling = 10 + dim.y_sampling = 10 sensor_irra.set_type_radiometric() sensor_irra.commit() speos_results, vtp_results = sim.compute_CPU(export_vtp=True) @@ -1102,7 +1110,9 @@ def test_export_vtp(speos: Speos): ) sim = p7.find(name=".*", name_regex=True, feature_type=SimulationDirect)[0] sensor_irra = p7.find(name=".*", name_regex=True, feature_type=SensorIrradiance)[0] - sensor_irra.set_dimensions().set_x_sampling(10).set_y_sampling(10) + dim = sensor_irra.set_dimensions() + dim.x_sampling = 10 + dim.y_sampling = 10 sensor_irra.set_type_colorimetric() sensor_irra.commit() @@ -1124,7 +1134,9 @@ def test_export_vtp(speos: Speos): ) sim = p8.find(name=".*", name_regex=True, feature_type=SimulationDirect)[0] sensor_irra = p8.find(name=".*", name_regex=True, feature_type=SensorIrradiance)[0] - sensor_irra.set_dimensions().set_x_sampling(10).set_y_sampling(10) + dim = sensor_irra.set_dimensions() + dim.x_sampling = 10 + dim.y_sampling = 10 sensor_irra.set_type_spectral() sensor_irra.commit() speos_results, vtp_results = sim.compute_CPU(export_vtp=True) From 8eaaf6ec7995093bc676676053efb7ceb2c9f0dd Mon Sep 17 00:00:00 2001 From: sthoene Date: Fri, 29 Aug 2025 13:43:54 +0200 Subject: [PATCH 17/47] fix example --- examples/core/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/core/sensor.py b/examples/core/sensor.py index 8e73afa50..4e4b822cb 100644 --- a/examples/core/sensor.py +++ b/examples/core/sensor.py @@ -137,7 +137,7 @@ def create_face(body): sensor2 = p.create_sensor(name="Camera.2", feature_type=SensorCamera) sensor2.distortion_file_uri = distortion_file_path photometric = sensor2.set_mode_photometric() -photometric.transmittance_file_uri(uri=transmittance_file_path) +photometric.transmittance_file_uri = transmittance_file_path photometric.set_layer_type_source() color = photometric.set_mode_color() color.blue_spectrum_file_uri = blue_spectrum_path From e84a11e48607758362e564d4adbe8c4019c602f1 Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 1 Sep 2025 08:29:30 +0200 Subject: [PATCH 18/47] fix example --- examples/workflow/combine-speos.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/examples/workflow/combine-speos.py b/examples/workflow/combine-speos.py index ad47b70a5..59a24bc98 100644 --- a/examples/workflow/combine-speos.py +++ b/examples/workflow/combine-speos.py @@ -113,18 +113,24 @@ # ### Create a sensor ssr = p.create_sensor(name="Camera.1", feature_type=SensorCamera) -ssr.set_distortion_file_uri( - uri=str(assets_data_path / "CameraInputFiles" / "CameraDistortion_190deg.OPTDistortion") -).set_mode_photometric().set_transmittance_file_uri( - uri=str(assets_data_path / "CameraInputFiles" / "CameraTransmittance.spectrum") -).set_mode_color().set_red_spectrum_file_uri( - uri=str(assets_data_path / "CameraInputFiles" / "CameraSensitivityRed.spectrum") -).set_blue_spectrum_file_uri( - uri=str(assets_data_path / "CameraInputFiles" / "CameraSensitivityBlue.spectrum") -).set_green_spectrum_file_uri( - uri=str(assets_data_path / "CameraInputFiles" / "CameraSensitivityGreen.spectrum") +ssr.distortion_file_uri = str( + assets_data_path / "CameraInputFiles" / "CameraDistortion_190deg.OPTDistortion" ) -ssr.set_axis_system([-2000, 1500, 11000, -1, 0, 0, 0, 1, 0, 0, 0, -1]) +ssr.set_mode_photometric().transmittance_file_uri = str( + assets_data_path / "CameraInputFiles" / "CameraTransmittance.spectrum" +) +color_mode = ssr.set_mode_photometric().set_mode_color() +color_mode.red_spectrum_file_uri = str( + assets_data_path / "CameraInputFiles" / "CameraSensitivityRed.spectrum" +) +color_mode.blue_spectrum_file_uri = str( + assets_data_path / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" +) +color_mode.green_spectrum_file_uri = str( + assets_data_path / "CameraInputFiles" / "CameraSensitivityGreen.spectrum" +) + +ssr.axis_system = [-2000, 1500, 11000, -1, 0, 0, 0, 1, 0, 0, 0, -1] ssr.commit() # ### Create a source @@ -195,7 +201,7 @@ # Modify the camera, e.g. focal length to 10 cam1 = p.find(name="Camera.1", feature_type=SensorCamera)[0] -cam1.set_focal_length(value=10) +cam1.focal_length = 10 cam1.commit() # Re-run the simulation and review result From 9896428caed62bc7d1417786f05f1cc98a470762 Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 1 Sep 2025 09:00:27 +0200 Subject: [PATCH 19/47] improve test coverage --- tests/core/test_sensor.py | 240 +++++++++++++++++--------------------- 1 file changed, 109 insertions(+), 131 deletions(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index 8b4d9b51b..db243045b 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -513,9 +513,17 @@ def test_create_irradiance_sensor(speos: Speos): sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.HasField("sensor_type_spectral") assert sensor_template.sensor_type_spectral.HasField("wavelengths_range") - assert sensor_template.sensor_type_spectral.wavelengths_range.w_start == 400 - assert sensor_template.sensor_type_spectral.wavelengths_range.w_end == 700 - assert sensor_template.sensor_type_spectral.wavelengths_range.w_sampling == 13 + assert ( + sensor_template.sensor_type_spectral.wavelengths_range.w_start + == SENSOR.WAVELENGTHSRANGE.START + ) + assert ( + sensor_template.sensor_type_spectral.wavelengths_range.w_end == SENSOR.WAVELENGTHSRANGE.END + ) + assert ( + sensor_template.sensor_type_spectral.wavelengths_range.w_sampling + == SENSOR.WAVELENGTHSRANGE.SAMPLING + ) # chosen wavelengths range wavelengths_range = sensor1.set_type_spectral().set_wavelengths_range() wavelengths_range.start = 450 @@ -680,6 +688,7 @@ def test_create_irradiance_sensor(speos: Speos): layer_by_sequence.set_define_sequence_per_faces() sensor1.commit() assert irra_properties.HasField("layer_type_sequence") + assert layer_by_sequence.maximum_nb_of_sequence == 5 assert irra_properties.layer_type_sequence.maximum_nb_of_sequence == 5 assert ( irra_properties.layer_type_sequence.define_sequence_per @@ -703,6 +712,7 @@ def test_create_irradiance_sensor(speos: Speos): sensor1.set_layer_type_incidence_angle().sampling = 8 sensor1.commit() assert irra_properties.HasField("layer_type_incidence_angle") + assert sensor1.set_layer_type_incidence_angle().sampling == 8 assert irra_properties.layer_type_incidence_angle.sampling == 8 # layer_type_none @@ -755,10 +765,12 @@ def test_create_radiance_sensor(speos: Speos): sensor1.sensor_template_link.get().radiance_sensor_template.focal == SENSOR.RADIANCESENSOR.FOCAL_LENGTH ) + assert sensor1.focal == SENSOR.RADIANCESENSOR.FOCAL_LENGTH assert ( sensor1.sensor_template_link.get().radiance_sensor_template.integration_angle == SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE ) + assert sensor1.integration_angle == SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField("dimensions") assert ( sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_start @@ -772,6 +784,7 @@ def test_create_radiance_sensor(speos: Speos): sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_sampling == SENSOR.DIMENSIONS.X_SAMPLING ) + assert sensor1.set_dimensions().x_sampling == SENSOR.DIMENSIONS.X_SAMPLING assert ( sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_start == SENSOR.DIMENSIONS.Y_START @@ -784,6 +797,7 @@ def test_create_radiance_sensor(speos: Speos): sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_sampling == SENSOR.DIMENSIONS.Y_SAMPLING ) + assert sensor1.set_dimensions().y_sampling == SENSOR.DIMENSIONS.Y_SAMPLING assert sensor1._sensor_instance.HasField("radiance_properties") radiance_properties = sensor1._sensor_instance.radiance_properties assert radiance_properties.axis_system == ORIGIN @@ -894,6 +908,11 @@ def test_create_radiance_sensor(speos: Speos): # observer_point sensor1.observer_point = [20, 30, 50] + assert sensor1.observer_point == [ + 20, + 30, + 50, + ] sensor1.commit() assert radiance_properties.observer_point == [ 20, @@ -1076,8 +1095,8 @@ def test_create_3d_irradiance_sensor(speos: Speos): sensor_3d.commit() assert sensor_3d.sensor_template_link.get().irradiance_3d.HasField("type_colorimetric") colorimetric_info = sensor_3d.sensor_template_link.get().irradiance_3d.type_colorimetric - assert colorimetric_info.wavelength_start == 400 - assert colorimetric_info.wavelength_end == 700 + assert colorimetric_info.wavelength_start == SENSOR.WAVELENGTHSRANGE.START + assert colorimetric_info.wavelength_end == SENSOR.WAVELENGTHSRANGE.END wavelengths_range = sensor_3d.set_type_colorimetric().set_wavelengths_range() wavelengths_range.start = 500 sensor_3d.commit() @@ -1152,38 +1171,16 @@ def test_reset_sensor(speos: Speos): # Create + commit sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorIrradiance) sensor1.commit() - assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == -50 # local assert ( - sensor1.sensor_template_link.get().irradiance_sensor_template.dimensions.x_start == -50 + sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start + == SENSOR.DIMENSIONS.X_START + ) # local + assert ( + sensor1.sensor_template_link.get().irradiance_sensor_template.dimensions.x_start + == SENSOR.DIMENSIONS.X_START ) # server - assert sensor1._sensor_instance.irradiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] # local - assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] # server + assert sensor1._sensor_instance.irradiance_properties.axis_system == ORIGIN # local + assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == ORIGIN # server sensor1.dimensions.x_start = 0 sensor1.axis_system = [1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1] @@ -1205,55 +1202,20 @@ def test_reset_sensor(speos: Speos): 0, 1, ] # local - assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] # server + assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == ORIGIN # server # Ask for reset sensor1.reset() - assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == -50 # local assert ( - sensor1.sensor_template_link.get().irradiance_sensor_template.dimensions.x_start == -50 + sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start + == SENSOR.DIMENSIONS.X_START + ) # local + assert ( + sensor1.sensor_template_link.get().irradiance_sensor_template.dimensions.x_start + == SENSOR.DIMENSIONS.X_START ) # server - assert sensor1._sensor_instance.irradiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] # local - assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] # server + assert sensor1._sensor_instance.irradiance_properties.axis_system == ORIGIN # local + assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == ORIGIN # server sensor1.delete() @@ -1280,7 +1242,7 @@ def test_irradiance_modify_after_reset(speos: Speos): # Intermediate class for type : spectral assert ( sensor1._sensor_template.irradiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start - == 400 + == SENSOR.WAVELENGTHSRANGE.START ) sensor1.set_type_spectral().set_wavelengths_range().start = 500 assert ( @@ -1288,25 +1250,15 @@ def test_irradiance_modify_after_reset(speos: Speos): == 500 ) # Intermediate class for dimensions - assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == -50 + assert ( + sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start + == SENSOR.DIMENSIONS.X_START + ) sensor1.set_dimensions().x_start = -100 assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == -100 # Props - assert sensor1._sensor_instance.irradiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] + assert sensor1._sensor_instance.irradiance_properties.axis_system == ORIGIN sensor1.axis_system = [50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_instance.irradiance_properties.axis_system == [ 50, @@ -1325,7 +1277,7 @@ def test_irradiance_modify_after_reset(speos: Speos): # Intermediate class for layer type assert ( sensor1._sensor_instance.irradiance_properties.layer_type_sequence.maximum_nb_of_sequence - == 10 + == SENSOR.LAYERTYPES.MAXIMUM_NB_OF_SEQUENCE ) sensor1.set_layer_type_sequence().maximum_nb_of_sequence = 15 assert ( @@ -1352,13 +1304,25 @@ def test_radiance_modify_after_reset(speos: Speos): # Modify after a reset # Template - assert sensor1._sensor_template.radiance_sensor_template.focal == 250 + assert ( + sensor1._sensor_template.radiance_sensor_template.focal + == SENSOR.RADIANCESENSOR.FOCAL_LENGTH + ) sensor1.focal = 100 assert sensor1._sensor_template.radiance_sensor_template.focal == 100 # Intermediate class for type : colorimetric assert ( sensor1._sensor_template.radiance_sensor_template.sensor_type_colorimetric.wavelengths_range.w_start - == 400 + == SENSOR.WAVELENGTHSRANGE.START + ) + sensor1.set_type_colorimetric().set_wavelengths_range().start = 500 + assert ( + sensor1._sensor_template.radiance_sensor_template.sensor_type_colorimetric.wavelengths_range.w_start + == 500 + ) + assert ( + sensor1._sensor_template.radiance_sensor_template.sensor_type_colorimetric.wavelengths_range.w_end + == SENSOR.WAVELENGTHSRANGE.END ) sensor1.set_type_colorimetric().set_wavelengths_range().start = 500 assert ( @@ -1366,25 +1330,40 @@ def test_radiance_modify_after_reset(speos: Speos): == 500 ) # Intermediate class for dimensions - assert sensor1._sensor_template.radiance_sensor_template.dimensions.x_start == -50 + assert ( + sensor1._sensor_template.radiance_sensor_template.dimensions.x_start + == SENSOR.DIMENSIONS.X_START + ) sensor1.set_dimensions().x_start = -100 assert sensor1._sensor_template.radiance_sensor_template.dimensions.x_start == -100 + assert sensor1.set_dimensions().x_start == -100 + + assert ( + sensor1._sensor_template.radiance_sensor_template.dimensions.x_end + == SENSOR.DIMENSIONS.X_END + ) + sensor1.set_dimensions().x_end = 100 + assert sensor1._sensor_template.radiance_sensor_template.dimensions.x_end == 100 + assert sensor1.set_dimensions().x_end == 100 + + assert ( + sensor1._sensor_template.radiance_sensor_template.dimensions.y_start + == SENSOR.DIMENSIONS.Y_START + ) + sensor1.set_dimensions().y_start = -100 + assert sensor1._sensor_template.radiance_sensor_template.dimensions.y_start == -100 + assert sensor1.set_dimensions().y_start == -100 + + assert ( + sensor1._sensor_template.radiance_sensor_template.dimensions.y_end + == SENSOR.DIMENSIONS.Y_END + ) + sensor1.set_dimensions().y_end = 100 + assert sensor1._sensor_template.radiance_sensor_template.dimensions.y_end == 100 + assert sensor1.set_dimensions().y_end == 100 ## Props - assert sensor1._sensor_instance.radiance_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] + assert sensor1._sensor_instance.radiance_properties.axis_system == ORIGIN sensor1.axis_system = [50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_instance.radiance_properties.axis_system == [ 50, @@ -1403,7 +1382,7 @@ def test_radiance_modify_after_reset(speos: Speos): # Intermediate class for layer type assert ( sensor1._sensor_instance.radiance_properties.layer_type_sequence.maximum_nb_of_sequence - == 10 + == SENSOR.LAYERTYPES.MAXIMUM_NB_OF_SEQUENCE ) sensor1.set_layer_type_sequence().maximum_nb_of_sequence = 15 assert ( @@ -1440,23 +1419,35 @@ def test_camera_modify_after_reset(speos: Speos): # Modify after a reset # Template - assert sensor1._sensor_template.camera_sensor_template.focal_length == 5 + assert ( + sensor1._sensor_template.camera_sensor_template.focal_length + == SENSOR.CAMERASENSOR.FOCAL_LENGTH + ) sensor1.focal_length = 40 assert sensor1._sensor_template.camera_sensor_template.focal_length == 40 # Intermediate class for mode : photometric + wavelengths assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_start - == 400 + == SENSOR.WAVELENGTHSRANGE.START ) sensor1.set_mode_photometric().set_wavelengths_range().start = 500 assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_start == 500 ) + assert ( + sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_end + == SENSOR.WAVELENGTHSRANGE.END + ) + sensor1.set_mode_photometric().set_wavelengths_range().end = 800 + assert ( + sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_end + == 800 + ) # Intermediate class for color mode + balance mode assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain - == 1 + == SENSOR.CAMERASENSOR.GAIN ) color = sensor1.set_mode_photometric().set_mode_color() white_mode = color.set_balance_mode_user_white() @@ -1467,20 +1458,7 @@ def test_camera_modify_after_reset(speos: Speos): ) # Props - assert sensor1._sensor_instance.camera_properties.axis_system == [ - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - ] + assert sensor1._sensor_instance.camera_properties.axis_system == ORIGIN sensor1.axis_system = [50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_instance.camera_properties.axis_system == [ 50, From 019b7391b227bfba306f84cfee97bae3bd5c83df Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 1 Sep 2025 16:57:37 +0200 Subject: [PATCH 20/47] improve test coverage --- src/ansys/speos/core/sensor.py | 8 ++-- tests/core/test_sensor.py | 69 ++++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 751458dda..003eefa48 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -559,12 +559,12 @@ class FaceLayer: def __init__(self, name: str, geometries: List[GeoRef]) -> None: self.name = name """Name of the layer""" - self.geometries = geometries + self.geometry = geometries @property def geometry(self): """List of geometries included in this layer.""" - return self._geometries + return self._geometry @geometry.setter def geometry(self, value): @@ -574,7 +574,7 @@ def geometry(self, value): geo_paths.append(gr) elif isinstance(gr, (face.Face, body.Body, part.Part.SubPart)): geo_paths.append(gr.geo_path) - self._geometries = geo_paths + self._geometry = geo_paths class LayerTypeFace: """Type of layer : Face. @@ -661,7 +661,7 @@ def set_layers(self, values: List[BaseSensor.FaceLayer]) -> BaseSensor.LayerType ProtoScene.SensorInstance.LayerTypeFace.Layer( name=layer.name, geometries=ProtoScene.GeoPaths( - geo_paths=[gr.to_native_link() for gr in layer.geometries] + geo_paths=[gr.to_native_link() for gr in layer.geometry] ), ) for layer in values diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index db243045b..9b55d93f4 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -127,24 +127,28 @@ def test_create_camera_sensor(speos: Speos): sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.horz_pixel == 680 + assert sensor1.horz_pixel == 680 # vert_pixel sensor1.vert_pixel = 500 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.vert_pixel == 500 + assert sensor1.vert_pixel == 500 # width sensor1.width = 5.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.width == 5.5 + assert sensor1.width == 5.5 # height sensor1.height = 5.3 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.height == 5.3 + assert sensor1.height == 5.3 # sensor_mode_geometric sensor1.set_mode_geometric() @@ -173,12 +177,14 @@ def test_create_camera_sensor(speos: Speos): sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.acquisition_integration == 0.03 + assert sensor1.photometric.acquisition_integration == 0.03 # acquisition_lag_time sensor1.photometric.acquisition_lag_time = 0.1 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.acquisition_lag_time == 0.1 + assert sensor1.photometric.acquisition_lag_time == 0.1 # transmittance_file_uri sensor1.photometric.transmittance_file_uri = str( @@ -187,12 +193,14 @@ def test_create_camera_sensor(speos: Speos): sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.transmittance_file_uri != "" + assert sensor1.photometric.transmittance_file_uri != "" # gamma_correction sensor1.photometric.gamma_correction = 2.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.sensor_mode_photometric.gamma_correction == 2.5 + assert sensor1.photometric.gamma_correction == 2.5 # png_bits sensor1.photometric.set_png_bits_08() @@ -301,6 +309,9 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_color.balance_mode_userwhite.red_gain == 2 assert mode_photometric.color_mode_color.balance_mode_userwhite.green_gain == 3 assert mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain == 4 + assert balance_mode_user_white.red_gain == 2 + assert balance_mode_user_white.green_gain == 3 + assert balance_mode_user_white.blue_gain == 4 # balance_mode_display display_primaries = ( @@ -328,6 +339,15 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_color.balance_mode_display.blue_display_file_uri.endswith( "CameraSensitivityBlue.spectrum" ) + assert display_primaries.red_display_file_uri == str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityRed.spectrum" + ) + assert display_primaries.green_display_file_uri == str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityGreen.spectrum" + ) + assert display_primaries.blue_display_file_uri == str( + Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" + ) # balance_mode_none sensor1.set_mode_photometric().set_mode_color().set_balance_mode_none() @@ -347,6 +367,9 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.wavelengths_range.w_start == 430 assert mode_photometric.wavelengths_range.w_end == 750 assert mode_photometric.wavelengths_range.w_sampling == 15 + assert wavelengths_range.start == 430 + assert wavelengths_range.end == 750 + assert wavelengths_range.sampling == 15 # Properties @@ -367,7 +390,20 @@ def test_create_camera_sensor(speos: Speos): 0, 1, ] - + assert sensor1.axis_system == [ + 10, + 50, + 20, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + ] # Properties for camera photometric # layer_type_source @@ -644,22 +680,20 @@ def test_create_irradiance_sensor(speos: Speos): assert irra_properties.HasField("layer_type_source") # layer_type_face + layer1 = sensor.BaseSensor.FaceLayer( + name="Layer.1", geometries=[GeoRef.from_native_link("TheBodyB")] + ) + layer1.geometry = [body_b] + layer2 = sensor.BaseSensor.FaceLayer( + name="Layer.2", + geometries=[ + GeoRef.from_native_link("TheBodyC/TheFaceC1"), + GeoRef.from_native_link("TheBodyC/TheFaceC2"), + ], + ) layer_face = sensor1.set_layer_type_face() layer_face.set_sca_filtering_mode_intersected_one_time() - layer_face.set_layers( - values=[ - sensor.BaseSensor.FaceLayer( - name="Layer.1", geometries=[GeoRef.from_native_link("TheBodyB")] - ), - sensor.BaseSensor.FaceLayer( - name="Layer.2", - geometries=[ - GeoRef.from_native_link("TheBodyC/TheFaceC1"), - GeoRef.from_native_link("TheBodyC/TheFaceC2"), - ], - ), - ] - ) + layer_face.set_layers(values=[layer1, layer2]) sensor1.commit() assert irra_properties.HasField("layer_type_face") assert ( @@ -674,7 +708,10 @@ def test_create_irradiance_sensor(speos: Speos): "TheBodyC/TheFaceC1", "TheBodyC/TheFaceC2", ] - + assert layer1.name == "Layer.1" + assert layer2.name == "Layer.2" + for geo_path in layer1.geometry: + assert isinstance(geo_path, GeoRef) layer_face.set_sca_filtering_mode_last_impact() sensor1.commit() assert ( From 24d607d46a30333546c94add8b507d711311e2d2 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Mon, 1 Sep 2025 14:58:50 +0000 Subject: [PATCH 21/47] chore: adding changelog file 691.miscellaneous.md [dependabot-skip] --- doc/changelog.d/691.miscellaneous.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog.d/691.miscellaneous.md b/doc/changelog.d/691.miscellaneous.md index 696fd0c0a..85b1388b6 100644 --- a/doc/changelog.d/691.miscellaneous.md +++ b/doc/changelog.d/691.miscellaneous.md @@ -1 +1 @@ -Sensor \ No newline at end of file +Sensor From c6701ff1b489e7acbcdb9e85c2296966f617a92c Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 1 Sep 2025 17:27:30 +0200 Subject: [PATCH 22/47] improve test coverage --- tests/core/test_sensor.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index 9b55d93f4..e73e86360 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -71,6 +71,7 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.acquisition_integration == SENSOR.CAMERASENSOR.ACQUISITION_INTEGRATION assert mode_photometric.acquisition_lag_time == SENSOR.CAMERASENSOR.ACQUISITION_LAG_TIME assert mode_photometric.transmittance_file_uri == "" + assert mode_photometric.trajectory_file_uri == "" assert math.isclose( a=mode_photometric.gamma_correction, b=SENSOR.CAMERASENSOR.GAMMA_CORRECTION, @@ -101,18 +102,21 @@ def test_create_camera_sensor(speos: Speos): sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.focal_length == 5.5 + assert sensor1.focal_length == 5.5 # imager_distance sensor1.imager_distance = 10.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.imager_distance == 10.5 + assert sensor1.imager_distance == 10.5 # f_number sensor1.f_number = 20.5 sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.f_number == 20.5 + assert sensor1.f_number == 20.5 # distortion_file_uri sensor1.distortion_file_uri = str( @@ -121,6 +125,7 @@ def test_create_camera_sensor(speos: Speos): sensor1.commit() camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template assert camera_sensor_template.distortion_file_uri != "" + assert sensor1.distortion_file_uri != "" # horz_pixel sensor1.horz_pixel = 680 @@ -270,6 +275,9 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_color.blue_spectrum_file_uri.endswith( "CameraSensitivityBlue.spectrum" ) + assert color.red_spectrum_file_uri.endswith("CameraSensitivityRed.spectrum") + assert color.green_spectrum_file_uri.endswith("CameraSensitivityRed.spectrum") + assert color.blue_spectrum_file_uri.endswith("CameraSensitivityRed.spectrum") # balance_mode_greyworld sensor1.set_mode_photometric().set_mode_color().set_balance_mode_grey_world() @@ -535,7 +543,9 @@ def test_create_irradiance_sensor(speos: Speos): assert sensor_template.sensor_type_colorimetric.wavelengths_range.w_start == 450 assert sensor_template.sensor_type_colorimetric.wavelengths_range.w_end == 800 assert sensor_template.sensor_type_colorimetric.wavelengths_range.w_sampling == 15 - + assert wavelengths_range.start == 450 + assert wavelengths_range.end == 800 + assert wavelengths_range.sampling == 15 # sensor_type_radiometric sensor1.set_type_radiometric() sensor1.commit() @@ -570,6 +580,9 @@ def test_create_irradiance_sensor(speos: Speos): assert sensor_template.sensor_type_spectral.wavelengths_range.w_start == 450 assert sensor_template.sensor_type_spectral.wavelengths_range.w_end == 800 assert sensor_template.sensor_type_spectral.wavelengths_range.w_sampling == 15 + assert wavelengths_range.start == 450 + assert wavelengths_range.end == 800 + assert wavelengths_range.sampling == 15 # sensor_type_photometric sensor1.set_type_photometric() @@ -607,9 +620,11 @@ def test_create_irradiance_sensor(speos: Speos): sensor1.commit() sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.HasField("illuminance_type_planar") + assert sensor1.integration_direction == [0, 0, -1] sensor1.integration_direction = None # cancel integration direction assert irra_properties.integration_direction == [] + assert sensor1.integration_direction == [] # dimensions sensor1.dimensions.x_start = -10 @@ -646,7 +661,7 @@ def test_create_irradiance_sensor(speos: Speos): 0, 1, ] - + assert sensor1.axis_system == [10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1] # ray_file_type sensor1.set_ray_file_type_classic() sensor1.commit() @@ -760,11 +775,11 @@ def test_create_irradiance_sensor(speos: Speos): # output_face_geometries sensor1.output_face_geometries = [ GeoRef.from_native_link(geopath="TheBodyB/TheFaceB1"), - GeoRef.from_native_link(geopath="TheBodyB/TheFaceB2"), + body_b, ] assert irra_properties.output_face_geometries.geo_paths == [ "TheBodyB/TheFaceB1", - "TheBodyB/TheFaceB2", + "TheBodyB", ] # output_face_geometries @@ -942,6 +957,7 @@ def test_create_radiance_sensor(speos: Speos): 0, 1, ] + assert sensor1.axis_system == [10, 50, 20, 1, 0, 0, 0, 1, 0, 0, 0, 1] # observer_point sensor1.observer_point = [20, 30, 50] @@ -1047,6 +1063,7 @@ def test_create_3d_irradiance_sensor(speos: Speos): body = p.find(name="PrismBody", name_regex=True, feature_type=Body)[0] sensor_3d = p.create_sensor(name="3d", feature_type=Sensor3DIrradiance) sensor_3d.geometries = [body.geo_path] + sensor_3d.geometries = [body] sensor_3d.commit() # when creating 3D irradiance, default properties: From dcd03135406de120f911d67aca99ff497160440e Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 1 Sep 2025 17:38:51 +0200 Subject: [PATCH 23/47] fix unit test --- tests/core/test_sensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index e73e86360..de34fe03e 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -71,7 +71,6 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.acquisition_integration == SENSOR.CAMERASENSOR.ACQUISITION_INTEGRATION assert mode_photometric.acquisition_lag_time == SENSOR.CAMERASENSOR.ACQUISITION_LAG_TIME assert mode_photometric.transmittance_file_uri == "" - assert mode_photometric.trajectory_file_uri == "" assert math.isclose( a=mode_photometric.gamma_correction, b=SENSOR.CAMERASENSOR.GAMMA_CORRECTION, @@ -95,6 +94,7 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_color.HasField("balance_mode_none") assert sensor1._sensor_instance.camera_properties.axis_system == ORIGIN assert sensor1._sensor_instance.camera_properties.trajectory_file_uri == "" + assert sensor1.set_mode_photometric().trajectory_file_uri == "" assert sensor1._sensor_instance.camera_properties.HasField("layer_type_none") # focal_length @@ -276,8 +276,8 @@ def test_create_camera_sensor(speos: Speos): "CameraSensitivityBlue.spectrum" ) assert color.red_spectrum_file_uri.endswith("CameraSensitivityRed.spectrum") - assert color.green_spectrum_file_uri.endswith("CameraSensitivityRed.spectrum") - assert color.blue_spectrum_file_uri.endswith("CameraSensitivityRed.spectrum") + assert color.green_spectrum_file_uri.endswith("CameraSensitivityGreen.spectrum") + assert color.blue_spectrum_file_uri.endswith("CameraSensitivityBlue.spectrum") # balance_mode_greyworld sensor1.set_mode_photometric().set_mode_color().set_balance_mode_grey_world() From 9eea447b94c4712d619aa654ba396aef55d2ca67 Mon Sep 17 00:00:00 2001 From: sthoene Date: Wed, 3 Sep 2025 16:02:35 +0200 Subject: [PATCH 24/47] improve docstrings --- src/ansys/speos/core/sensor.py | 154 ++++++++++++++++----------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 003eefa48..1f0e69cc5 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -170,7 +170,7 @@ def __init__( @property def start(self) -> float: - """The minimum wavelength of the range.""" + """Minimum wavelength of the range.""" if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): return self._wavelengths_range.w_start else: @@ -178,7 +178,7 @@ def start(self) -> float: @start.setter def start(self, value: float): - """Set the minimum wavelength of the range. + """Minimum wavelength of the range. Parameters ---------- @@ -192,7 +192,7 @@ def start(self, value: float): @property def end(self) -> float: - """Set the maximum wavelength of the range. + """Maximum wavelength of the range. By default, ``700``. """ @@ -203,7 +203,7 @@ def end(self) -> float: @end.setter def end(self, value: float): - """Set the maximum wavelength of the range. + """Maximum wavelength of the range. Parameters ---------- @@ -217,7 +217,7 @@ def end(self, value: float): @property def sampling(self) -> int: - """Set the sampling of wavelengths range. + """Wavelength sampling of between start and end value. By default, ``13``. """ @@ -226,7 +226,7 @@ def sampling(self) -> int: @sampling.setter def sampling(self, value: int = 13): - """Set the sampling of wavelengths range. + """Wavelength sampling of between start and end value. Parameters ---------- @@ -279,7 +279,7 @@ def __init__( @property def x_start(self) -> float: - """Set the minimum value on x axis. + """Minimum value on x axis. By default, ``-50``. @@ -292,7 +292,7 @@ def x_start(self) -> float: @x_start.setter def x_start(self, value: float): - """Set the minimum value on x axis. + """Minimum value on x axis. Parameters ---------- @@ -303,7 +303,7 @@ def x_start(self, value: float): @property def x_end(self) -> float: - """Set the maximum value on x axis. + """Maximum value on x axis. By default, ``50``. @@ -316,7 +316,7 @@ def x_end(self) -> float: @x_end.setter def x_end(self, value: float): - """Set the maximum value on x axis. + """Maximum value on x axis. Parameters ---------- @@ -327,7 +327,7 @@ def x_end(self, value: float): @property def x_sampling(self) -> int: - """Set the sampling value on x axis. + """Value of the sampling on x axis. By default, ``100``. @@ -340,7 +340,7 @@ def x_sampling(self) -> int: @x_sampling.setter def x_sampling(self, value: int): - """Set the sampling value on x axis. + """Value of the sampling on x axis. Parameters ---------- @@ -351,7 +351,7 @@ def x_sampling(self, value: int): @property def y_start(self) -> float: - """Set the minimum value on y axis. + """Minimum value on y axis. By default, ``-50``. @@ -364,7 +364,7 @@ def y_start(self) -> float: @y_start.setter def y_start(self, value: float): - """Set the minimum value on y axis. + """Minimum value on y axis. Parameters ---------- @@ -375,7 +375,7 @@ def y_start(self, value: float): @property def y_end(self) -> float: - """Set the maximum value on y axis. + """Maximum value on y axis. By default, ``50``. @@ -388,7 +388,7 @@ def y_end(self) -> float: @y_end.setter def y_end(self, value: float): - """Set the maximum value on y axis. + """Maximum value on y axis. Parameters ---------- @@ -399,7 +399,7 @@ def y_end(self, value: float): @property def y_sampling(self) -> int: - """Set the sampling value on y axis. + """Value of the sampling on y axis. By default, ``100``. @@ -412,7 +412,7 @@ def y_sampling(self) -> int: @y_sampling.setter def y_sampling(self, value: int): - """Set the sampling value on y axis. + """Value of the sampling on y axis. Parameters ---------- @@ -711,7 +711,7 @@ def __init__( @property def maximum_nb_of_sequence(self) -> int: - """Set the maximum number of sequences. + """Value of the maximum number of sequences. By default, ``10``. @@ -724,7 +724,7 @@ def maximum_nb_of_sequence(self) -> int: @maximum_nb_of_sequence.setter def maximum_nb_of_sequence(self, value: int): - """Set the maximum number of sequences. + """Value of the maximum number of sequences. Parameters ---------- @@ -801,7 +801,7 @@ def __init__( @property def sampling(self) -> BaseSensor.LayerTypeIncidenceAngle: - """Set the sampling for incidence angles. + """Value of the sampling for incidence angles. Parameters ---------- @@ -818,7 +818,7 @@ def sampling(self) -> BaseSensor.LayerTypeIncidenceAngle: @sampling.setter def sampling(self, value: int) -> BaseSensor.LayerTypeIncidenceAngle: - """Set the sampling for incidence angles. + """Value of the sampling for incidence angles. Parameters ---------- @@ -1142,7 +1142,7 @@ def __init__( @property def red_gain(self) -> float: - """The red gain value of the Camera Sensor. + """Value of the red gain of the Camera Sensor. By default, ``1``. """ @@ -1161,7 +1161,7 @@ def red_gain(self, value: float): @property def green_gain(self) -> float: - """The green gain value of the Camera Sensor. + """Value of the green gain of the Camera Sensor. By default, ``1``. """ @@ -1180,7 +1180,7 @@ def green_gain(self, value: float): @property def blue_gain(self) -> float: - """The bkue gain value of the Camera Sensor. + """Value of the Blue gain of the Camera Sensor. By default, ``1``. """ @@ -1188,7 +1188,7 @@ def blue_gain(self) -> float: @blue_gain.setter def blue_gain(self, value: float): - """Set blue gain. + """Set blue gain value. Parameters ---------- @@ -1240,12 +1240,12 @@ def __init__( @property def red_display_file_uri(self) -> str: - """The red display file.""" + """Location of the red display file.""" return self._balance_mode_display.red_display_file_uri @red_display_file_uri.setter def red_display_file_uri(self, uri: str): - """Set the red display file. + """Location of the red display file. Parameters ---------- @@ -1256,12 +1256,12 @@ def red_display_file_uri(self, uri: str): @property def green_display_file_uri(self) -> str: - """The green display file.""" + """Location of the green display file.""" return self._balance_mode_display.green_display_file_uri @green_display_file_uri.setter def green_display_file_uri(self, uri: str): - """Set the green display file. + """Location of the green display file. Parameters ---------- @@ -1272,12 +1272,12 @@ def green_display_file_uri(self, uri: str): @property def blue_display_file_uri(self) -> str: - """The blue display file.""" + """Location of the blue display file.""" return self._balance_mode_display.blue_display_file_uri @blue_display_file_uri.setter def blue_display_file_uri(self, uri: str): - """Set the blue display file. + """Location of the blue display file. Parameters ---------- @@ -1306,12 +1306,12 @@ def __init__( @property def red_spectrum_file_uri(self) -> str: - """The red spectrum.""" + """Location of the red spectrum.""" return self._mode_color.red_spectrum_file_uri @red_spectrum_file_uri.setter def red_spectrum_file_uri(self, uri: str): - """Set the red spectrum. + """Location of the red spectrum. Parameters ---------- @@ -1322,12 +1322,12 @@ def red_spectrum_file_uri(self, uri: str): @property def blue_spectrum_file_uri(self) -> str: - """The blue spectrum.""" + """Location of the blue spectrum.""" return self._mode_color.blue_spectrum_file_uri @blue_spectrum_file_uri.setter def blue_spectrum_file_uri(self, uri: str): - """Set the blue spectrum. + """Location of the blue spectrum. Parameters ---------- @@ -1338,12 +1338,12 @@ def blue_spectrum_file_uri(self, uri: str): @property def green_spectrum_file_uri(self) -> str: - """The green spectrum.""" + """Location of the green spectrum.""" return self._mode_color.green_spectrum_file_uri @green_spectrum_file_uri.setter def green_spectrum_file_uri(self, uri: str): - """Set the green spectrum. + """Location of the green spectrum. Parameters ---------- @@ -1492,7 +1492,7 @@ def __init__( @property def acquisition_integration(self) -> float: - """The acquisition integration value. + """Value of the acquisition integration. By default, ``0.01``. """ @@ -1500,7 +1500,7 @@ def acquisition_integration(self) -> float: @acquisition_integration.setter def acquisition_integration(self, value: float): - """Set the acquisition integration value. + """Value of the acquisition integration. Parameters ---------- @@ -1511,8 +1511,8 @@ def acquisition_integration(self, value: float): self._mode_photometric.acquisition_integration = value @property - def acquisition_lag_time(self, value: float = 0.0) -> float: - """The acquisition lag time value. + def acquisition_lag_time(self) -> float: + """Value of the acquisition lag time. By default, ``0.0``. """ @@ -1520,7 +1520,7 @@ def acquisition_lag_time(self, value: float = 0.0) -> float: @acquisition_lag_time.setter def acquisition_lag_time(self, value: float): - """Set the acquisition lag time value. + """Value of the acquisition lag time. Parameters ---------- @@ -1537,12 +1537,12 @@ def acquisition_lag_time(self, value: float): @property def transmittance_file_uri(self) -> str: - """The transmittance file.""" + """Location of the transmittance file.""" return self._mode_photometric.transmittance_file_uri @transmittance_file_uri.setter def transmittance_file_uri(self, uri: str): - """Set the transmittance file. + """Location of the transmittance file. Parameters ---------- @@ -1554,7 +1554,7 @@ def transmittance_file_uri(self, uri: str): @property def gamma_correction(self) -> float: - """Set the gamma correction. + """Value used to apply the gamma correction. By default, ``2.2``. """ @@ -1562,7 +1562,7 @@ def gamma_correction(self) -> float: @gamma_correction.setter def gamma_correction(self, value: float): - """Set the gamma correction. + """Value used to apply the gamma correction. By default, ``2.2``. """ @@ -1679,12 +1679,12 @@ def set_mode_color(self) -> SensorCamera.Photometric.Color: @property def trajectory_file_uri(self) -> str: - """The trajectory file.""" + """Location of the trajectory file.""" return self._camera_props.trajectory_file_uri @trajectory_file_uri.setter def trajectory_file_uri(self, uri: str): - """Set the trajectory file. + """Location of the trajectory file. Parameters ---------- @@ -1853,7 +1853,7 @@ def photometric(self) -> Union[SensorCamera.Photometric, None]: @property def focal_length(self) -> float: - """The focal length. + """Focal length of the optical system. By default, ``5.0``. """ @@ -1861,7 +1861,7 @@ def focal_length(self) -> float: @focal_length.setter def focal_length(self, value: float) -> SensorCamera: - """Set the focal length. + """Focal length of the optical system. Parameters ---------- @@ -1873,7 +1873,7 @@ def focal_length(self, value: float) -> SensorCamera: @property def imager_distance(self) -> SensorCamera: - """Set the imager distance. + """Imager distance. By default, ``10``. """ @@ -1881,7 +1881,7 @@ def imager_distance(self) -> SensorCamera: @imager_distance.setter def imager_distance(self, value: float): - """Set the imager distance. + """Imager distance. Parameters ---------- @@ -1894,7 +1894,7 @@ def imager_distance(self, value: float): @property def f_number(self) -> float: - """Set the f number. + """F number of the optical system. By default, ``20``. """ @@ -1902,7 +1902,7 @@ def f_number(self) -> float: @f_number.setter def f_number(self, value: float = 20): - """Set the f number. + """F number of the optical system. Parameters ---------- @@ -1915,12 +1915,12 @@ def f_number(self, value: float = 20): @property def distortion_file_uri(self) -> str: - """Set the distortion file.""" + """Location of the distortion file.""" return self._sensor_template.camera_sensor_template.distortion_file_uri @distortion_file_uri.setter def distortion_file_uri(self, uri: str): - """Set the distortion file. + """Location of the distortion file. Parameters ---------- @@ -1932,12 +1932,12 @@ def distortion_file_uri(self, uri: str): @property def horz_pixel(self) -> int: - """The horizontal pixels number corresponding to the camera resolution.""" + """Horizontal pixels number corresponding to the camera resolution.""" return self._sensor_template.camera_sensor_template.horz_pixel @horz_pixel.setter def horz_pixel(self, value: int): - """Set the horizontal pixels number corresponding to the camera resolution. + """Horizontal pixels number corresponding to the camera resolution. Parameters ---------- @@ -1949,7 +1949,7 @@ def horz_pixel(self, value: int): @property def vert_pixel(self) -> int: - """The vertical pixels number corresponding to the camera resolution. + """Vertical pixels number corresponding to the camera resolution. By default, ``480``. """ @@ -1957,7 +1957,7 @@ def vert_pixel(self) -> int: @vert_pixel.setter def vert_pixel(self, value: int): - """Set the vertical pixels number corresponding to the camera resolution. + """Vertical pixels number corresponding to the camera resolution. Parameters ---------- @@ -1969,7 +1969,7 @@ def vert_pixel(self, value: int): @property def width(self) -> float: - """The width of the sensor. + """Width of the imager. By default, ``5.0``. """ @@ -1977,7 +1977,7 @@ def width(self) -> float: @width.setter def width(self, value: float): - """Set the width of the sensor. + """Width of the imager. Parameters ---------- @@ -1989,7 +1989,7 @@ def width(self, value: float): @property def height(self) -> float: - """The height of the sensor. + """Height of the imager. Parameters ---------- @@ -2001,7 +2001,7 @@ def height(self) -> float: @height.setter def height(self, value: float): - """Set the height of the sensor. + """Height of the imager. Parameters ---------- @@ -2021,7 +2021,7 @@ def axis_system(self) -> List[float]: @axis_system.setter def axis_system(self, axis_system: List[float]): - """Set the position of the sensor. + """Position of the sensor. Parameters ---------- @@ -2557,7 +2557,7 @@ def set_illuminance_type_semi_cylindrical(self) -> SensorIrradiance: @property def axis_system(self) -> List[float]: - """The position of the sensor. + """Position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ @@ -2565,7 +2565,7 @@ def axis_system(self) -> List[float]: @axis_system.setter def axis_system(self, axis_system: List[float]): - """Set the position of the sensor. + """Position of the sensor. Parameters ---------- @@ -3157,7 +3157,7 @@ def set_type_spectral(self) -> BaseSensor.Spectral: @property def focal(self) -> float: - """The focal value of the Radiance Sensor. + """Focal value of the Radiance Sensor. By default, ``250``. @@ -3170,7 +3170,7 @@ def focal(self) -> float: @focal.setter def focal(self, value: float): - """Set the focal value. + """Focal value. Parameters ---------- @@ -3182,7 +3182,7 @@ def focal(self, value: float): @property def integration_angle(self) -> float: - """Set the integration angle. + """Integration angle. By default, ``5``. @@ -3195,7 +3195,7 @@ def integration_angle(self) -> float: @integration_angle.setter def integration_angle(self, value: float) -> SensorRadiance: - """Set the integration angle. + """Integration angle. Parameters ---------- @@ -3207,7 +3207,7 @@ def integration_angle(self, value: float) -> SensorRadiance: @property def axis_system(self) -> List[float]: - """The position of the sensor. + """Position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ @@ -3215,7 +3215,7 @@ def axis_system(self) -> List[float]: @axis_system.setter def axis_system(self, axis_system: List[float]): - """Set the position of the sensor. + """Position of the sensor. Parameters ---------- @@ -3227,7 +3227,7 @@ def axis_system(self, axis_system: List[float]): @property def observer_point(self) -> SensorRadiance: - """Set the position of the observer point. + """The position of the observer point. This is optional, because the focal length is used by default. Choosing to set an observer point will make the focal length ignored. @@ -3243,7 +3243,7 @@ def observer_point(self) -> SensorRadiance: @observer_point.setter def observer_point(self, value: Optional[List[float]]): - """Set the position of the observer point. + """Position of the observer point. This is optional, because the focal length is used by default. Choosing to set an observer point will make the focal length ignored. @@ -3632,7 +3632,7 @@ def transmission(self) -> bool: @transmission.setter def transmission(self, value: bool) -> None: - """Set transmission. + """Transmission. Parameters ---------- From 2553947a7a285b5613a0a6004745809d536bea20 Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 9 Sep 2025 08:37:33 +0200 Subject: [PATCH 25/47] improve docstrings --- src/ansys/speos/core/sensor.py | 250 +++++++++++++++++++++++++++------ 1 file changed, 210 insertions(+), 40 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 1f0e69cc5..b1773daa5 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -111,8 +111,14 @@ def __init__( self.reset() @property - def lxp_path_number(self): - """Number of LXP rays simulated for the Sensor.""" + def lxp_path_number(self) -> int: + """Number of LXP rays simulated for the Sensor. + + Returns + ------- + int + Number of Rays stored in the lpf file for this Sensor + """ if self._sensor_instance.HasField("lxp_properties"): return self._sensor_instance.lxp_properties.nb_max_paths return None @@ -170,7 +176,15 @@ def __init__( @property def start(self) -> float: - """Minimum wavelength of the range.""" + """Minimum wavelength of the range. + + By default, ``400``. + + Returns + ------- + float + Lower Bound of the wavelength range. + """ if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): return self._wavelengths_range.w_start else: @@ -195,6 +209,11 @@ def end(self) -> float: """Maximum wavelength of the range. By default, ``700``. + + Returns + ------- + float + Upper Bound of the wavelength range. """ if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): return self._wavelengths_range.w_end @@ -220,12 +239,17 @@ def sampling(self) -> int: """Wavelength sampling of between start and end value. By default, ``13``. + + Returns + ------- + int + Number of Samples used to split the wavelength range. """ if isinstance(self._wavelengths_range, common_pb2.WavelengthsRange): return self._wavelengths_range.w_sampling @sampling.setter - def sampling(self, value: int = 13): + def sampling(self, value): """Wavelength sampling of between start and end value. Parameters @@ -563,11 +587,26 @@ def __init__(self, name: str, geometries: List[GeoRef]) -> None: @property def geometry(self): - """List of geometries included in this layer.""" + """List of geometries included in this layer. + + Returns + ------- + List[GeoRef] + List of the Geometries contained in the FaceLayer group + """ return self._geometry @geometry.setter - def geometry(self, value): + def geometry( + self, value: Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] + ): + """Set the geometry for this Face Layer group. + + Parameters + ---------- + value : Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] + Geometry within the Face Layer group + """ geo_paths = [] for gr in value: if isinstance(gr, GeoRef): @@ -644,18 +683,28 @@ def set_sca_filtering_mode_last_impact( ) return self - def set_layers(self, values: List[BaseSensor.FaceLayer]) -> BaseSensor.LayerTypeFace: + @property + def layers(self) -> List[BaseSensor.FaceLayer]: + """List of Face layer Groups of this sensor. + + Returns + ------- + List[ansys.speos.core.sensor.BaseSensor.FaceLayer] + List of FaceLayer Classes + """ + layer_data = [] + for layer in self._layer_type_face.layers: + layer_data.append(BaseSensor.FaceLayer(layer.name, layer.geometries)) + return layer_data + + @layers.setter + def layers(self, values: List[BaseSensor.FaceLayer]): """Set the layers. Parameters ---------- values : List[ansys.speos.core.sensor.BaseSensor.FaceLayer] List of layers - - Returns - ------- - ansys.speos.core.sensor.BaseSensor.LayerTypeFace - LayerTypeFace. """ my_list = [ ProtoScene.SensorInstance.LayerTypeFace.Layer( @@ -668,7 +717,6 @@ def set_layers(self, values: List[BaseSensor.FaceLayer]) -> BaseSensor.LayerType ] self._layer_type_face.ClearField("layers") self._layer_type_face.layers.extend(my_list) - return self class LayerTypeSequence: """Type of layer : Sequence. @@ -803,16 +851,12 @@ def __init__( def sampling(self) -> BaseSensor.LayerTypeIncidenceAngle: """Value of the sampling for incidence angles. - Parameters - ---------- - value : int - Sampling for incidence angles. - By default, ``9``. + By default, ``9``. Returns ------- - ansys.speos.core.sensor.BaseSensor.LayerTypeIncidenceAngle - LayerTypeIncidenceAngle. + int + Sampling for incidence angles. """ return self._layer_type_incidence_angle.sampling @@ -825,11 +869,6 @@ def sampling(self, value: int) -> BaseSensor.LayerTypeIncidenceAngle: value : int Sampling for incidence angles. By default, ``9``. - - Returns - ------- - ansys.speos.core.sensor.BaseSensor.LayerTypeIncidenceAngle - LayerTypeIncidenceAngle. """ self._layer_type_incidence_angle.sampling = value @@ -1145,6 +1184,11 @@ def red_gain(self) -> float: """Value of the red gain of the Camera Sensor. By default, ``1``. + + Returns + ------- + float + Red gain. """ return self._balance_mode_user_white.red_gain @@ -1164,6 +1208,11 @@ def green_gain(self) -> float: """Value of the green gain of the Camera Sensor. By default, ``1``. + + Returns + ------- + float + green gain. """ return self._balance_mode_user_white.green_gain @@ -1183,6 +1232,11 @@ def blue_gain(self) -> float: """Value of the Blue gain of the Camera Sensor. By default, ``1``. + + Returns + ------- + float + blue gain. """ return self._balance_mode_user_white.blue_gain @@ -1240,7 +1294,13 @@ def __init__( @property def red_display_file_uri(self) -> str: - """Location of the red display file.""" + """Location of the red display file. + + Returns + ------- + str + Red display file. + """ return self._balance_mode_display.red_display_file_uri @red_display_file_uri.setter @@ -1256,7 +1316,13 @@ def red_display_file_uri(self, uri: str): @property def green_display_file_uri(self) -> str: - """Location of the green display file.""" + """Location of the green display file. + + Returns + ------- + str + green display file. + """ return self._balance_mode_display.green_display_file_uri @green_display_file_uri.setter @@ -1272,7 +1338,13 @@ def green_display_file_uri(self, uri: str): @property def blue_display_file_uri(self) -> str: - """Location of the blue display file.""" + """Location of the blue display file. + + Returns + ------- + str + blue display file. + """ return self._balance_mode_display.blue_display_file_uri @blue_display_file_uri.setter @@ -1306,7 +1378,13 @@ def __init__( @property def red_spectrum_file_uri(self) -> str: - """Location of the red spectrum.""" + """Location of the red spectrum. + + Returns + ------- + str + Red spectrum file. It is expressed in a .spectrum file. + """ return self._mode_color.red_spectrum_file_uri @red_spectrum_file_uri.setter @@ -1322,7 +1400,13 @@ def red_spectrum_file_uri(self, uri: str): @property def blue_spectrum_file_uri(self) -> str: - """Location of the blue spectrum.""" + """Location of the blue spectrum. + + Returns + ------- + str + blue spectrum file. It is expressed in a .spectrum file. + """ return self._mode_color.blue_spectrum_file_uri @blue_spectrum_file_uri.setter @@ -1338,7 +1422,13 @@ def blue_spectrum_file_uri(self, uri: str): @property def green_spectrum_file_uri(self) -> str: - """Location of the green spectrum.""" + """Location of the green spectrum. + + Returns + ------- + str + green spectrum file. It is expressed in a .spectrum file. + """ return self._mode_color.green_spectrum_file_uri @green_spectrum_file_uri.setter @@ -1495,6 +1585,11 @@ def acquisition_integration(self) -> float: """Value of the acquisition integration. By default, ``0.01``. + + Returns + ------- + float + Acquisition integration value (s). """ return self._mode_photometric.acquisition_integration @@ -1515,6 +1610,11 @@ def acquisition_lag_time(self) -> float: """Value of the acquisition lag time. By default, ``0.0``. + + Returns + ------- + float + Acquisition lag time value (s). """ return self._mode_photometric.acquisition_lag_time @@ -1537,7 +1637,13 @@ def acquisition_lag_time(self, value: float): @property def transmittance_file_uri(self) -> str: - """Location of the transmittance file.""" + """Location of the transmittance file. + + Returns + ------- + str + Amount of light of the source that passes through the lens and reaches the sensor. + """ return self._mode_photometric.transmittance_file_uri @transmittance_file_uri.setter @@ -1557,6 +1663,11 @@ def gamma_correction(self) -> float: """Value used to apply the gamma correction. By default, ``2.2``. + + Returns + ------- + float + Gamma Correction value """ return self._mode_photometric.gamma_correction @@ -1565,6 +1676,11 @@ def gamma_correction(self, value: float): """Value used to apply the gamma correction. By default, ``2.2``. + + Parameters + ---------- + value : float + Gamma Correction value """ self._mode_photometric.gamma_correction = value @@ -1679,7 +1795,14 @@ def set_mode_color(self) -> SensorCamera.Photometric.Color: @property def trajectory_file_uri(self) -> str: - """Location of the trajectory file.""" + """Location of the trajectory file. + + Returns + ------- + str + Trajectory file, used to define the position and orientations of the Camera sensor + in time. + """ return self._camera_props.trajectory_file_uri @trajectory_file_uri.setter @@ -1856,6 +1979,11 @@ def focal_length(self) -> float: """Focal length of the optical system. By default, ``5.0``. + + Returns + ------- + float + Distance between the center of the optical system and the focus. (mm) """ return self._sensor_template.camera_sensor_template.focal_length @@ -1876,6 +2004,12 @@ def imager_distance(self) -> SensorCamera: """Imager distance. By default, ``10``. + + Returns + ------- + float + Imager distance (mm). The imager is located at the focal point. + The Imager distance has no impact on the result. """ return self._sensor_template.camera_sensor_template.imager_distance @@ -1897,6 +2031,12 @@ def f_number(self) -> float: """F number of the optical system. By default, ``20``. + + Returns + ------- + float + F-number represents the aperture of the front lens. + F number has no impact on the result. """ return self._sensor_template.camera_sensor_template.f_number @@ -1915,7 +2055,14 @@ def f_number(self, value: float = 20): @property def distortion_file_uri(self) -> str: - """Location of the distortion file.""" + """Location of the distortion file. + + Returns + ------- + str + Optical aberration that deforms and bends straight lines. The distortion is expressed in + a .OPTDistortion file. + """ return self._sensor_template.camera_sensor_template.distortion_file_uri @distortion_file_uri.setter @@ -1932,7 +2079,13 @@ def distortion_file_uri(self, uri: str): @property def horz_pixel(self) -> int: - """Horizontal pixels number corresponding to the camera resolution.""" + """Horizontal pixels number corresponding to the camera resolution. + + Returns + ------- + int + The horizontal pixels number corresponding to the camera resolution. + """ return self._sensor_template.camera_sensor_template.horz_pixel @horz_pixel.setter @@ -1952,6 +2105,11 @@ def vert_pixel(self) -> int: """Vertical pixels number corresponding to the camera resolution. By default, ``480``. + + Returns + ------- + int + The vertical pixels number corresponding to the camera resolution. """ return self._sensor_template.camera_sensor_template.vert_pixel @@ -1972,6 +2130,11 @@ def width(self) -> float: """Width of the imager. By default, ``5.0``. + + Returns + ------- + float + Sensor's width (mm). """ return self._sensor_template.camera_sensor_template.width @@ -1991,11 +2154,13 @@ def width(self, value: float): def height(self) -> float: """Height of the imager. - Parameters - ---------- - value : float + By default, ``5.0`` + + Returns + ------- + float Sensor's height (mm). - By default, ``5.0``. + `. """ return self._sensor_template.camera_sensor_template.height @@ -2016,6 +2181,11 @@ def axis_system(self) -> List[float]: """The position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + + Returns + ------- + List[float] + Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. """ return self._sensor_instance.camera_properties.axis_system @@ -2025,7 +2195,7 @@ def axis_system(self, axis_system: List[float]): Parameters ---------- - axis_system : Optional[List[float]] + axis_system : List[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ From 732c066aabadb87e93f11fde3d944b3558264856 Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 9 Sep 2025 08:38:11 +0200 Subject: [PATCH 26/47] refactor to dataclasses --- src/ansys/speos/core/generic/constants.py | 149 ++++++++++++---------- 1 file changed, 84 insertions(+), 65 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index eee286017..04aa71229 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -24,6 +24,8 @@ import os +from attr import dataclass + DEFAULT_HOST: str = "localhost" """Default host used by Speos RPC server and client """ DEFAULT_PORT: str = "50098" @@ -43,71 +45,88 @@ """Global Origin""" +@dataclass(frozen=True) +class WavelengthsRange: + """Wavelength constants.""" + + START = 400 + """Wavelength start value.""" + END = 700 + """Wavelength end value.""" + SAMPLING = 13 + """Wavelength sampling.""" + + +@dataclass(frozen=True) +class Dimensions: + """Dimension Constants.""" + + X_START = -50 + """Lower bound x axis.""" + X_END = 50 + """Upper bound x axis.""" + X_SAMPLING = 100 + """Sampling x axis.""" + Y_START = -50 + """Lower bound y axis.""" + Y_END = 50 + """Upper bound y axis.""" + Y_SAMPLING = 100 + """Sampling y axis.""" + + +@dataclass(frozen=True) +class LayerTypes: + """Layer Separation constants.""" + + MAXIMUM_NB_OF_SEQUENCE = 10 + """Number of sequences stored in sensor.""" + INCIDENCE_SAMPLING = 9 + """Number of incidence sampling stored in sensor.""" + + +@dataclass(frozen=True) +class CameraSensor: + """Camera Sensor Constants.""" + + GAIN = 1 + """Default gain value of the Camera Sensor.""" + ACQUISITION_INTEGRATION = 0.01 + """Default integration Time value for the Camera Sensor.""" + ACQUISITION_LAG_TIME = 0 + """Default acquisition lag time for the Camera Sensor.""" + GAMMA_CORRECTION = 2.2 + """Default gamma correction Value for the Camera Sensor.""" + FOCAL_LENGTH = 5 + """Default focal length of the Camera Sensor.""" + IMAGER_DISTANCE = 10 + """Default imager distance of the camera sensor.""" + F_NUMBER = 20 + """Default f number of the camera sensor.""" + HORZ_PIXEL = 640 + """Default pixel number in horizontal direction.""" + VERT_PIXEL = 480 + """Default pixel number in vertical direction.""" + WIDTH = 5.0 + """Default width of the camera chip.""" + HEIGHT = 5.0 + """Default height of the camera chip.""" + + +@dataclass(frozen=True) +class RadianceSensor: + """Radiance Sensor Constants.""" + + FOCAL_LENGTH = 250 + INTEGRATION_ANGLE = 5 + + +@dataclass(frozen=True) class SENSOR: """Constant class for Sensors.""" - class WAVELENGTHSRANGE: - """Wavelength constants.""" - - START = 400 - """Wavelength start value.""" - END = 700 - """Wavelength end value.""" - SAMPLING = 13 - """Wavelength sampling.""" - - class DIMENSIONS: - """Dimension Constants.""" - - X_START = -50 - """Lower bound x axis.""" - X_END = 50 - """Upper bound x axis.""" - X_SAMPLING = 100 - """Sampling x axis.""" - Y_START = -50 - """Lower bound y axis.""" - Y_END = 50 - """Upper bound y axis.""" - Y_SAMPLING = 100 - """Sampling y axis.""" - - class LAYERTYPES: - """Layer Separation constants.""" - - MAXIMUM_NB_OF_SEQUENCE = 10 - """Number of sequences stored in sensor.""" - INCIDENCE_SAMPLING = 9 - """Number of incidence sampling stored in sensor.""" - - class CAMERASENSOR: - """Camera Sensor Constants.""" - - GAIN = 1 - """Default gain value of the Camera Sensor.""" - ACQUISITION_INTEGRATION = 0.01 - """Default integration Time value for the Camera Sensor.""" - ACQUISITION_LAG_TIME = 0 - """Default acquisition lag time for the Camera Sensor.""" - GAMMA_CORRECTION = 2.2 - """Default gamma correction Value for the Camera Sensor.""" - FOCAL_LENGTH = 5 - """Default focal length of the Camera Sensor.""" - IMAGER_DISTANCE = 10 - """Default imager distance of the camera sensor.""" - F_NUMBER = 20 - """Default f number of the camera sensor.""" - HORZ_PIXEL = 640 - """Default pixel number in horizontal direction.""" - VERT_PIXEL = 480 - """Default pixel number in vertical direction.""" - WIDTH = 5.0 - """Default width of the camera chip.""" - HEIGHT = 5.0 - """Default height of the camera chip.""" - - class RADIANCESENSOR: - """Radiance Sensor Constants.""" - - FOCAL_LENGTH = 250 - INTEGRATION_ANGLE = 5 + WAVELENGTHSRANGE = WavelengthsRange() + DIMENSIONS = Dimensions() + LAYERTYPES = LayerTypes() + CAMERASENSOR = CameraSensor() + RADIANCESENSOR = RadianceSensor() From 41b3d7e4b9f359398ef85b2596832b4f26aaf7f8 Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 9 Sep 2025 08:44:28 +0200 Subject: [PATCH 27/47] Improve doc strings --- src/ansys/speos/core/sensor.py | 38 ++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index b1773daa5..fac9852b4 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -2730,6 +2730,11 @@ def axis_system(self) -> List[float]: """Position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + + Returns + ------- + List[float] + Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. """ return self._sensor_instance.irradiance_properties.axis_system @@ -2739,7 +2744,7 @@ def axis_system(self, axis_system: List[float]): Parameters ---------- - axis_system : Optional[List[float]] + axis_system : List[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ @@ -3380,6 +3385,11 @@ def axis_system(self) -> List[float]: """Position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. + + Returns + ------- + List[float] + Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. """ return self._sensor_instance.radiance_properties.axis_system @@ -3389,7 +3399,7 @@ def axis_system(self, axis_system: List[float]): Parameters ---------- - axis_system : Optional[List[float]] + axis_system : List[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ @@ -3406,13 +3416,14 @@ def observer_point(self) -> SensorRadiance: Returns ------- - ansys.speos.core.sensor.SensorRadiance - Radiance sensor. + Union[None, List[float]] + Position of the observer point [Ox Oy Oz], None means that the + focal length is used. """ return self._sensor_instance.radiance_properties.observer_point @observer_point.setter - def observer_point(self, value: Optional[List[float]]): + def observer_point(self, value: List[float]): """Position of the observer point. This is optional, because the focal length is used by default. @@ -3420,7 +3431,7 @@ def observer_point(self, value: Optional[List[float]]): Parameters ---------- - value : List[float], optional + value : List[float] Position of the observer point [Ox Oy Oz]. By default, ``None``. None means that the focal length is used. """ @@ -4162,26 +4173,21 @@ def geometries(self) -> List[str]: Returns ------- - ansys.speos.core.sensor.Sensor3DIrradiance - 3D Irradiance sensor + List[str] + List of geometries that will be considered as Sensor """ return self._sensor_instance.irradiance_3d_properties.geometries.geo_paths @geometries.setter def geometries( - self, geometries: Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] + self, geometries: List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]] ) -> Sensor3DIrradiance: """Select geometry faces to be defined with 3D irradiance sensor. Parameters ---------- - geometries : List[ansys.speos.core.geo_ref.GeoRef] - List of geometries that will be considered as output faces. - - Returns - ------- - ansys.speos.core.sensor.Sensor3DIrradiance - 3D Irradiance sensor + geometries : List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]] + List of geometries that will be considered as Sensor """ geo_paths = [] for gr in geometries: From a2a6e8f35f3eb9b5164985ae43185b249a1d0995 Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 9 Sep 2025 09:08:12 +0200 Subject: [PATCH 28/47] allow path and str for all pathes --- src/ansys/speos/core/sensor.py | 65 ++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index fac9852b4..2b4d9fd27 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -25,6 +25,7 @@ from __future__ import annotations from difflib import SequenceMatcher +from pathlib import Path from typing import List, Mapping, Optional, Union import uuid import warnings @@ -1304,15 +1305,15 @@ def red_display_file_uri(self) -> str: return self._balance_mode_display.red_display_file_uri @red_display_file_uri.setter - def red_display_file_uri(self, uri: str): + def red_display_file_uri(self, uri: Union[str, Path]): """Location of the red display file. Parameters ---------- - uri : str + uri : Union[str, Path] Red display file. """ - self._balance_mode_display.red_display_file_uri = uri + self._balance_mode_display.red_display_file_uri = str(Path(uri)) @property def green_display_file_uri(self) -> str: @@ -1326,15 +1327,15 @@ def green_display_file_uri(self) -> str: return self._balance_mode_display.green_display_file_uri @green_display_file_uri.setter - def green_display_file_uri(self, uri: str): + def green_display_file_uri(self, uri: Union[str, Path]): """Location of the green display file. Parameters ---------- - uri : str + uri : Union[str, Path] green display file. """ - self._balance_mode_display.green_display_file_uri = uri + self._balance_mode_display.green_display_file_uri = str(Path(uri)) @property def blue_display_file_uri(self) -> str: @@ -1348,15 +1349,15 @@ def blue_display_file_uri(self) -> str: return self._balance_mode_display.blue_display_file_uri @blue_display_file_uri.setter - def blue_display_file_uri(self, uri: str): + def blue_display_file_uri(self, uri: Union[str, Path]): """Location of the blue display file. Parameters ---------- - uri : str + uri : Union[str, Path] blue display file. """ - self._balance_mode_display.blue_display_file_uri = uri + self._balance_mode_display.blue_display_file_uri = str(Path(uri)) def __init__( self, @@ -1388,15 +1389,15 @@ def red_spectrum_file_uri(self) -> str: return self._mode_color.red_spectrum_file_uri @red_spectrum_file_uri.setter - def red_spectrum_file_uri(self, uri: str): + def red_spectrum_file_uri(self, uri: Union[str, Path]): """Location of the red spectrum. Parameters ---------- - uri : str + uri : Union[str, Path] Red spectrum file. It is expressed in a .spectrum file. """ - self._mode_color.red_spectrum_file_uri = uri + self._mode_color.red_spectrum_file_uri = str(Path(uri)) @property def blue_spectrum_file_uri(self) -> str: @@ -1410,15 +1411,15 @@ def blue_spectrum_file_uri(self) -> str: return self._mode_color.blue_spectrum_file_uri @blue_spectrum_file_uri.setter - def blue_spectrum_file_uri(self, uri: str): + def blue_spectrum_file_uri(self, uri: Union[str, Path]): """Location of the blue spectrum. Parameters ---------- - uri : str + uri : Union[str, Path] blue spectrum file. It is expressed in a .spectrum file. """ - self._mode_color.blue_spectrum_file_uri = uri + self._mode_color.blue_spectrum_file_uri = str(Path(uri)) @property def green_spectrum_file_uri(self) -> str: @@ -1432,15 +1433,15 @@ def green_spectrum_file_uri(self) -> str: return self._mode_color.green_spectrum_file_uri @green_spectrum_file_uri.setter - def green_spectrum_file_uri(self, uri: str): + def green_spectrum_file_uri(self, uri: Union[str, Path]): """Location of the green spectrum. Parameters ---------- - uri : str + uri : Union[str, Path] green spectrum file. It is expressed in a .spectrum file. """ - self._mode_color.green_spectrum_file_uri = uri + self._mode_color.green_spectrum_file_uri = str(Path(uri)) def set_balance_mode_none(self) -> SensorCamera.Photometric.Color: """Set the balance mode as none. @@ -1647,16 +1648,16 @@ def transmittance_file_uri(self) -> str: return self._mode_photometric.transmittance_file_uri @transmittance_file_uri.setter - def transmittance_file_uri(self, uri: str): + def transmittance_file_uri(self, uri: Union[str, Path]): """Location of the transmittance file. Parameters ---------- - uri : str + uri : Union[str, Path] Amount of light of the source that passes through the lens and reaches the sensor. The transmittance is expressed in a .spectrum file. """ - self._mode_photometric.transmittance_file_uri = uri + self._mode_photometric.transmittance_file_uri = str(Path(uri)) @property def gamma_correction(self) -> float: @@ -1746,14 +1747,16 @@ def set_wavelengths_range(self) -> BaseSensor.WavelengthsRange: ) return self._wavelengths_range - def set_mode_monochromatic(self, spectrum_file_uri: str) -> SensorCamera.Photometric: + def set_mode_monochromatic( + self, spectrum_file_uri: Union[str, Path] + ) -> SensorCamera.Photometric: """Set the monochromatic mode. Results will be available in grey scale. Parameters ---------- - spectrum_file_uri : str + spectrum_file_uri : Union[str, Path] Spectrum file uri. Returns @@ -1762,7 +1765,9 @@ def set_mode_monochromatic(self, spectrum_file_uri: str) -> SensorCamera.Photome Photometric mode. """ self._mode = None - self._mode_photometric.color_mode_monochromatic.spectrum_file_uri = spectrum_file_uri + self._mode_photometric.color_mode_monochromatic.spectrum_file_uri = str( + Path(spectrum_file_uri) + ) return self def set_mode_color(self) -> SensorCamera.Photometric.Color: @@ -1806,16 +1811,16 @@ def trajectory_file_uri(self) -> str: return self._camera_props.trajectory_file_uri @trajectory_file_uri.setter - def trajectory_file_uri(self, uri: str): + def trajectory_file_uri(self, uri: Union[str, Path]): """Location of the trajectory file. Parameters ---------- - uri : str + uri : Union[str, Path] Trajectory file, used to define the position and orientations of the Camera sensor in time. """ - self._camera_props.trajectory_file_uri = uri + self._camera_props.trajectory_file_uri = str(Path(uri)) def set_layer_type_none(self) -> SensorCamera.Photometric: """Set no layer separation: includes the simulation's results in one layer. @@ -2066,16 +2071,16 @@ def distortion_file_uri(self) -> str: return self._sensor_template.camera_sensor_template.distortion_file_uri @distortion_file_uri.setter - def distortion_file_uri(self, uri: str): + def distortion_file_uri(self, uri: Union[str, Path]): """Location of the distortion file. Parameters ---------- - uri : str + uri : Union[str, Path] Optical aberration that deforms and bends straight lines. The distortion is expressed in a .OPTDistortion file. """ - self._sensor_template.camera_sensor_template.distortion_file_uri = uri + self._sensor_template.camera_sensor_template.distortion_file_uri = str(Path(uri)) @property def horz_pixel(self) -> int: From f52c32f1a48d7cfcdf86c32a7c6bfacda2693a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Th=C3=B6ne?= <86405327+StefanThoene@users.noreply.github.com> Date: Tue, 9 Sep 2025 10:08:55 +0200 Subject: [PATCH 29/47] fix dataclasses issue --- src/ansys/speos/core/generic/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 04aa71229..5c6f48ad6 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -24,7 +24,7 @@ import os -from attr import dataclass +from dataclasses import dataclass DEFAULT_HOST: str = "localhost" """Default host used by Speos RPC server and client """ From 6ccf764de6bf5859e7f16ba163015d58bdba3392 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 Sep 2025 08:09:50 +0000 Subject: [PATCH 30/47] ci: auto fixes from pre-commit.com hooks. for more information, see https://pre-commit.ci --- src/ansys/speos/core/generic/constants.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 5c6f48ad6..15c5c979d 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -22,9 +22,8 @@ """Collection of all constants used in pySpeos.""" -import os - from dataclasses import dataclass +import os DEFAULT_HOST: str = "localhost" """Default host used by Speos RPC server and client """ From dc70d4851e97e9620f2a9c32431bbf464ba36742 Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 9 Sep 2025 10:28:07 +0200 Subject: [PATCH 31/47] fix issue with layer property on test --- tests/core/test_sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index de34fe03e..8814444eb 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -708,7 +708,7 @@ def test_create_irradiance_sensor(speos: Speos): ) layer_face = sensor1.set_layer_type_face() layer_face.set_sca_filtering_mode_intersected_one_time() - layer_face.set_layers(values=[layer1, layer2]) + layer_face.layers = [layer1, layer2] sensor1.commit() assert irra_properties.HasField("layer_type_face") assert ( From 3b0d91404664d47522f486325910910d97ecabef Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 9 Sep 2025 10:38:10 +0200 Subject: [PATCH 32/47] fix issue with layer property on test --- tests/core/test_sensor.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index 8814444eb..efea5bbce 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -983,20 +983,18 @@ def test_create_radiance_sensor(speos: Speos): assert radiance_properties.HasField("layer_type_source") # layer_type_face - sensor1.set_layer_type_face().set_sca_filtering_mode_intersected_one_time().set_layers( - values=[ - sensor.BaseSensor.FaceLayer( - name="Layer.1", geometries=[GeoRef.from_native_link("TheBodyB")] - ), - sensor.BaseSensor.FaceLayer( - name="Layer.2", - geometries=[ - GeoRef.from_native_link("TheBodyC/TheFaceC1"), - GeoRef.from_native_link("TheBodyC/TheFaceC2"), - ], - ), - ] - ) + sensor1.set_layer_type_face().set_sca_filtering_mode_intersected_one_time().layers = [ + sensor.BaseSensor.FaceLayer( + name="Layer.1", geometries=[GeoRef.from_native_link("TheBodyB")] + ), + sensor.BaseSensor.FaceLayer( + name="Layer.2", + geometries=[ + GeoRef.from_native_link("TheBodyC/TheFaceC1"), + GeoRef.from_native_link("TheBodyC/TheFaceC2"), + ], + ), + ] sensor1.commit() assert radiance_properties.HasField("layer_type_face") assert ( From 4ca2d152781641f0dbfdfe6aa15bc8e418320260 Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 18 Sep 2025 15:40:36 +0200 Subject: [PATCH 33/47] intermediate step refactor --- src/ansys/speos/core/generic/constants.py | 206 ++++++++++++++++++---- src/ansys/speos/core/sensor.py | 123 ++++++++----- tests/core/test_sensor.py | 22 +-- 3 files changed, 260 insertions(+), 91 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 15c5c979d..508e64bd0 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -22,8 +22,13 @@ """Collection of all constants used in pySpeos.""" -from dataclasses import dataclass +from dataclasses import dataclass, field +from enum import Enum import os +from pathlib import Path +from typing import Union + +from ansys.speos.core import GeoRef, body, face, part DEFAULT_HOST: str = "localhost" """Default host used by Speos RPC server and client """ @@ -44,72 +49,195 @@ """Global Origin""" -@dataclass(frozen=True) +@dataclass class WavelengthsRange: """Wavelength constants.""" - START = 400 + start: int = 400 """Wavelength start value.""" - END = 700 + end: int = 700 """Wavelength end value.""" - SAMPLING = 13 + sampling: int = 13 """Wavelength sampling.""" -@dataclass(frozen=True) +@dataclass class Dimensions: """Dimension Constants.""" - X_START = -50 + x_start: float = -50 """Lower bound x axis.""" - X_END = 50 + x_end: float = 50 """Upper bound x axis.""" - X_SAMPLING = 100 + x_sampling: int = 100 """Sampling x axis.""" - Y_START = -50 + y_start: float = -50 """Lower bound y axis.""" - Y_END = 50 + y_end: float = 50 """Upper bound y axis.""" - Y_SAMPLING = 100 + y_sampling: int = 100 """Sampling y axis.""" -@dataclass(frozen=True) -class LayerTypes: - """Layer Separation constants.""" +class LayerTypes(str, Enum): + """Layer Separation types without parameters.""" - MAXIMUM_NB_OF_SEQUENCE = 10 - """Number of sequences stored in sensor.""" - INCIDENCE_SAMPLING = 9 - """Number of incidence sampling stored in sensor.""" + none = "none" + by_source = "by_source" + by_polarization = "by_polarization" -@dataclass(frozen=True) -class CameraSensor: - """Camera Sensor Constants.""" - - GAIN = 1 - """Default gain value of the Camera Sensor.""" - ACQUISITION_INTEGRATION = 0.01 - """Default integration Time value for the Camera Sensor.""" - ACQUISITION_LAG_TIME = 0 - """Default acquisition lag time for the Camera Sensor.""" - GAMMA_CORRECTION = 2.2 - """Default gamma correction Value for the Camera Sensor.""" - FOCAL_LENGTH = 5 +class SCAFilteringTypes(str, Enum): + """Surface contribution analyser filtering types.""" + + intersected_one_time = "intersected_one_time" + last_impact = "last_impact" + + +class SequenceTypes(str, Enum): + """Sequence types to separate the sequence data.""" + + by_face = "by_face" + by_geometry = "by_geometry" + + +@dataclass +class LayerBySequence: + """Layer separation type Parameters for Sequence separation.""" + + maximum_nb_of_sequence: int = 10 + sequence_type: Union[SequenceTypes.by_face, SequenceTypes.by_geometry] = ( + SequenceTypes.by_geometry + ) + + +@dataclass +class LayerByFace: + """Layer separation type Parameters for Face separation.""" + + geometries: list[list[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] = None + sca_filtering_types: Union[ + SCAFilteringTypes.intersected_one_time, SCAFilteringTypes.last_impact + ] = SCAFilteringTypes.last_impact + + +@dataclass +class LayerbyIncidenceAngle: + """Layer separation type Parameters for Incidence angle separation.""" + + incidence_sampling: int = 9 + + +class PngBits(str, Enum): + """Bit resolution of create PNG image.""" + + png_08 = "png_08" + png_10 = "png_10" + png_12 = "png_12" + png_16 = "png_16" + + +class ColorBalanceMode(str, Enum): + """Color Balance Mode types without parameters.""" + + none = "none" + grey_world = "grey_world" + + +@dataclass +class BalanceModeUserWhiteParameters: + """Parameters for Balance mode: User White.""" + + red_gain: float = 1.0 + """Gain value for Red.""" + green_gain: float = 1.0 + """Gain value for green.""" + blue_gain: float = 1.0 + """Gain value for blue.""" + + +@dataclass +class BalanceModeDisplayPrimariesParameters: + """Parameters for Balance mode: Display primaries.""" + + red_display_file_uri: Union[str, Path] = "" + """Spectrum path of the red display spectrum.""" + green_display_file_uri: Union[str, Path] = "" + """Spectrum path of the green display spectrum.""" + blue_display_file_uri: Union[str, Path] = "" + """Spectrum path of the red display spectrum.""" + + +@dataclass +class ColorParameters: + """Color mode Camera Parameter.""" + + balance_mode: Union[ + ColorBalanceMode.none, + ColorBalanceMode.grey_world, + BalanceModeUserWhiteParameters, + BalanceModeDisplayPrimariesParameters, + ] = ColorBalanceMode.none + """Camera Balance mode.""" + red_spectrum_file_uri: str = "" + """Path to sensitivity spectrum of red Channel.""" + green_spectrum_file_uri: str = "" + """Path to sensitivity spectrum of green Channel.""" + blue_spectrum_file_uri: str = "" + """Path to sensitivity spectrum of blue Channel.""" + + +@dataclass +class MonoChromaticParameters: + """Monochromatic Camera Parameters.""" + + sensitivity: str = "" + """Path to Sensitivity Spectrum.""" + + +@dataclass +class PhotometricCameraParameters: + """Photometric Parameters for Camera.""" + + color_mode: Union[MonoChromaticParameters, ColorParameters] = ColorParameters() + """Color mode of the Camera Sensor.""" + layer_type: Union[LayerTypes.none, LayerTypes.by_source] = LayerTypes.none + """Layer separation parameter.""" + png_bits: Union[PngBits.png_08, PngBits.png_10, PngBits.png_12, PngBits.png_16] = PngBits.png_16 + """PNG bit resolution of the Camera Sensor.""" + wavelength_range = WavelengthsRange() + """Wavelength range of the Camera Sensor.""" + ACQUISITION_INTEGRATION: float = 0.01 + """Integration Time value for the Camera Sensor.""" + ACQUISITION_LAG_TIME: float = 0 + """Acquisition lag time for the Camera Sensor.""" + GAMMA_CORRECTION: float = 2.2 + """Gamma correction Value for the Camera Sensor.""" + + +@dataclass +class CameraSensorParameters: + """Camera Sensor Parameters.""" + + sensor_type_parameters: Union[None, PhotometricCameraParameters] = PhotometricCameraParameters() + """Camera sensor type None means geometric sensor""" + axis_system: list[float] = field(default_factory=lambda: [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + """Location of the sensor Origin""" + focal_length: float = 5 """Default focal length of the Camera Sensor.""" - IMAGER_DISTANCE = 10 + imager_distance: float = 10 """Default imager distance of the camera sensor.""" - F_NUMBER = 20 + f_number: float = 20 """Default f number of the camera sensor.""" - HORZ_PIXEL = 640 + horz_pixel: int = 640 """Default pixel number in horizontal direction.""" - VERT_PIXEL = 480 + vert_pixel: int = 480 """Default pixel number in vertical direction.""" - WIDTH = 5.0 + width: float = 5.0 """Default width of the camera chip.""" - HEIGHT = 5.0 + height: float = 5.0 """Default height of the camera chip.""" + trajectory_fil_uri: Union[str, Path] = "" @dataclass(frozen=True) @@ -127,5 +255,5 @@ class SENSOR: WAVELENGTHSRANGE = WavelengthsRange() DIMENSIONS = Dimensions() LAYERTYPES = LayerTypes() - CAMERASENSOR = CameraSensor() + CAMERASENSOR = "" RADIANCESENSOR = RadianceSensor() diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 2b4d9fd27..40256d64c 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -37,7 +37,15 @@ import ansys.speos.core as core import ansys.speos.core.body as body import ansys.speos.core.face as face -from ansys.speos.core.generic.constants import ORIGIN, SENSOR +from ansys.speos.core.generic.constants import ( + ORIGIN, + SENSOR, + CameraSensorParameters, + ColorParameters, + MonoChromaticParameters, + PhotometricCameraParameters, + WavelengthsRange, +) import ansys.speos.core.generic.general_methods as general_methods from ansys.speos.core.generic.visualization_methods import _VisualData, local2absolute from ansys.speos.core.geo_ref import GeoRef @@ -161,7 +169,7 @@ class WavelengthsRange: def __init__( self, wavelengths_range: Union[common_pb2.WavelengthsRange, sensor_pb2.TypeColorimetric], - default_values: bool = True, + default_parameters: Union[None, WavelengthsRange] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -169,11 +177,11 @@ def __init__( raise RuntimeError(msg) self._wavelengths_range = wavelengths_range - if default_values: + if default_parameters: # Default values - self.start = SENSOR.WAVELENGTHSRANGE.START - self.end = SENSOR.WAVELENGTHSRANGE.END - self.sampling = SENSOR.WAVELENGTHSRANGE.SAMPLING + self.start = default_parameters.start + self.end = default_parameters.end + self.sampling = default_parameters.sampling @property def start(self) -> float: @@ -581,7 +589,7 @@ class FaceLayer: """ - def __init__(self, name: str, geometries: List[GeoRef]) -> None: + def __init__(self, name: str, geometries: list[GeoRef]) -> None: self.name = name """Name of the layer""" self.geometry = geometries @@ -592,20 +600,20 @@ def geometry(self): Returns ------- - List[GeoRef] + list[GeoRef] List of the Geometries contained in the FaceLayer group """ return self._geometry @geometry.setter def geometry( - self, value: Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] + self, value: Optional[list[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] ): """Set the geometry for this Face Layer group. Parameters ---------- - value : Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] + value : Optional[list[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] Geometry within the Face Layer group """ geo_paths = [] @@ -685,13 +693,13 @@ def set_sca_filtering_mode_last_impact( return self @property - def layers(self) -> List[BaseSensor.FaceLayer]: + def layers(self) -> list[BaseSensor.FaceLayer]: """List of Face layer Groups of this sensor. Returns ------- - List[ansys.speos.core.sensor.BaseSensor.FaceLayer] - List of FaceLayer Classes + list[ansys.speos.core.sensor.BaseSensor.FaceLayer] + list of FaceLayer Classes """ layer_data = [] for layer in self._layer_type_face.layers: @@ -1553,7 +1561,7 @@ def __init__( self, mode_photometric: camera_sensor_pb2.SensorCameraModePhotometric, camera_props: ProtoScene.SensorInstance.CameraProperties, - default_values: bool = True, + default_parameters: Union[None, PhotometricCameraParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -1566,20 +1574,43 @@ def __init__( self._mode = None # Attribute to keep track of wavelength range object - self._wavelengths_range = SensorCamera.WavelengthsRange( - wavelengths_range=self._mode_photometric.wavelengths_range, - stable_ctr=stable_ctr, - ) - if default_values: + if isinstance(default_parameters, PhotometricCameraParameters): # Default values - self.acquisition_integration = SENSOR.CAMERASENSOR.ACQUISITION_INTEGRATION - self.acquisition_lag_time = SENSOR.CAMERASENSOR.ACQUISITION_LAG_TIME - self.gamma_correction = SENSOR.CAMERASENSOR.GAMMA_CORRECTION - self.set_png_bits_16().set_mode_color() - self.set_wavelengths_range() - # Default values properties - self.set_layer_type_none() + self.acquisition_integration = default_parameters.ACQUISITION_INTEGRATION + self.acquisition_lag_time = default_parameters.ACQUISITION_LAG_TIME + self.gamma_correction = default_parameters.GAMMA_CORRECTION + match default_parameters.png_bits: + case "png_08": + self.set_png_bits_08() + case "png_10": + self.set_png_bits_10() + case "png_12": + self.set_png_bits_12() + case "png_16": + self.set_png_bits_16() + match default_parameters.layer_type: + case "none": + self.set_layer_type_none() + case "by_source": + self.set_layer_type_source() + self._wavelengths_range = SensorCamera.WavelengthsRange( + wavelengths_range=self._mode_photometric.wavelengths_range, + default_parameters=default_parameters.wavelength_range, + stable_ctr=stable_ctr, + ) + if isinstance(default_parameters.color_mode, MonoChromaticParameters): + self.set_mode_monochromatic(default_parameters.color_mode.sensitivity) + elif isinstance(default_parameters.color_mode, ColorParameters): + pass + elif default_parameters is None: + self._wavelengths_range = SensorCamera.WavelengthsRange( + wavelengths_range=self._mode_photometric.wavelengths_range, + default_parameters=None, + stable_ctr=stable_ctr, + ) + else: + raise TypeError("Default Photometric Parameters are incorrect") @property def acquisition_integration(self) -> float: @@ -1851,7 +1882,7 @@ def __init__( description: str = "", metadata: Optional[Mapping[str, str]] = None, sensor_instance: Optional[ProtoScene.SensorInstance] = None, - default_values: bool = True, + default_parameters: Union[None, CameraSensorParameters] = None, ) -> None: if metadata is None: metadata = {} @@ -1866,18 +1897,27 @@ def __init__( # Attribute gathering more complex camera mode self._type = None - if default_values: - # Default values template - self.imager_distance = SENSOR.CAMERASENSOR.IMAGER_DISTANCE - self.focal_length = SENSOR.CAMERASENSOR.FOCAL_LENGTH - self.f_number = SENSOR.CAMERASENSOR.F_NUMBER - self.horz_pixel = SENSOR.CAMERASENSOR.HORZ_PIXEL - self.vert_pixel = SENSOR.CAMERASENSOR.VERT_PIXEL - self.width = SENSOR.CAMERASENSOR.WIDTH - self.height = SENSOR.CAMERASENSOR.HEIGHT - self.axis_system = ORIGIN - - self.set_mode_photometric() + if sensor_instance is None: + if not default_parameters: + default_parameters = CameraSensorParameters() + self.imager_distance = default_parameters.imager_distance + self.focal_length = default_parameters.focal_length + self.f_number = default_parameters.f_number + self.horz_pixel = default_parameters.horz_pixel + self.vert_pixel = default_parameters.vert_pixel + self.width = default_parameters.width + self.height = default_parameters.height + self.axis_system = default_parameters.axis_system + + if isinstance(default_parameters.sensor_type_parameters, PhotometricCameraParameters): + self._type = SensorCamera.Photometric( + mode_photometric=self._sensor_template.camera_sensor_template.sensor_mode_photometric, + camera_props=self._sensor_instance.camera_properties, + default_parameters=default_parameters.sensor_type_parameters, + stable_ctr=True, + ) + else: + self.set_mode_geometric() @property def visual_data(self) -> _VisualData: @@ -2238,7 +2278,7 @@ def set_mode_photometric(self) -> SensorCamera.Photometric: self._type = SensorCamera.Photometric( mode_photometric=self._sensor_template.camera_sensor_template.sensor_mode_photometric, camera_props=self._sensor_instance.camera_properties, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, SensorCamera.Photometric): @@ -2246,6 +2286,7 @@ def set_mode_photometric(self) -> SensorCamera.Photometric: self._type = SensorCamera.Photometric( mode_photometric=self._sensor_template.camera_sensor_template.sensor_mode_photometric, camera_props=self._sensor_instance.camera_properties, + default_parameters=PhotometricCameraParameters(), stable_ctr=True, ) elif ( @@ -3075,7 +3116,7 @@ def __init__( if default_values: # Default values template - self.focal = SENSOR.RADIANCESENSOR.FOCAL_LENGTH + self.focal = SENSOR.RADIANCESENSOR.focal_length self.integration_angle = SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE self.set_type_photometric() # Default values properties diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index efea5bbce..ab98d9d74 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -58,14 +58,14 @@ def test_create_camera_sensor(speos: Speos): assert sensor1.sensor_template_link is not None assert sensor1.sensor_template_link.get().HasField("camera_sensor_template") camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template - assert camera_sensor_template.focal_length == SENSOR.CAMERASENSOR.FOCAL_LENGTH - assert camera_sensor_template.imager_distance == SENSOR.CAMERASENSOR.IMAGER_DISTANCE + assert camera_sensor_template.focal_length == SENSOR.CAMERASENSOR.focal_length + assert camera_sensor_template.imager_distance == SENSOR.CAMERASENSOR.imager_distance assert camera_sensor_template.distortion_file_uri == "" - assert camera_sensor_template.f_number == SENSOR.CAMERASENSOR.F_NUMBER - assert camera_sensor_template.horz_pixel == SENSOR.CAMERASENSOR.HORZ_PIXEL - assert camera_sensor_template.vert_pixel == SENSOR.CAMERASENSOR.VERT_PIXEL - assert camera_sensor_template.width == SENSOR.CAMERASENSOR.WIDTH - assert camera_sensor_template.height == SENSOR.CAMERASENSOR.HEIGHT + assert camera_sensor_template.f_number == SENSOR.CAMERASENSOR.f_number + assert camera_sensor_template.horz_pixel == SENSOR.CAMERASENSOR.horz_pixel + assert camera_sensor_template.vert_pixel == SENSOR.CAMERASENSOR.vert_pixel + assert camera_sensor_template.width == SENSOR.CAMERASENSOR.width + assert camera_sensor_template.height == SENSOR.CAMERASENSOR.height assert camera_sensor_template.HasField("sensor_mode_photometric") mode_photometric = camera_sensor_template.sensor_mode_photometric assert mode_photometric.acquisition_integration == SENSOR.CAMERASENSOR.ACQUISITION_INTEGRATION @@ -815,9 +815,9 @@ def test_create_radiance_sensor(speos: Speos): ) assert ( sensor1.sensor_template_link.get().radiance_sensor_template.focal - == SENSOR.RADIANCESENSOR.FOCAL_LENGTH + == SENSOR.RADIANCESENSOR.focal_length ) - assert sensor1.focal == SENSOR.RADIANCESENSOR.FOCAL_LENGTH + assert sensor1.focal == SENSOR.RADIANCESENSOR.focal_length assert ( sensor1.sensor_template_link.get().radiance_sensor_template.integration_angle == SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE @@ -1358,7 +1358,7 @@ def test_radiance_modify_after_reset(speos: Speos): # Template assert ( sensor1._sensor_template.radiance_sensor_template.focal - == SENSOR.RADIANCESENSOR.FOCAL_LENGTH + == SENSOR.RADIANCESENSOR.focal_length ) sensor1.focal = 100 assert sensor1._sensor_template.radiance_sensor_template.focal == 100 @@ -1473,7 +1473,7 @@ def test_camera_modify_after_reset(speos: Speos): # Template assert ( sensor1._sensor_template.camera_sensor_template.focal_length - == SENSOR.CAMERASENSOR.FOCAL_LENGTH + == SENSOR.CAMERASENSOR.focal_length ) sensor1.focal_length = 40 assert sensor1._sensor_template.camera_sensor_template.focal_length == 40 From b47ff29f06e9409b55ef9e8bcc0377e0b53be89f Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 18 Sep 2025 16:06:20 +0200 Subject: [PATCH 34/47] refactor camera sensor --- src/ansys/speos/core/sensor.py | 58 ++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 40256d64c..1de520bca 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -40,6 +40,8 @@ from ansys.speos.core.generic.constants import ( ORIGIN, SENSOR, + BalanceModeDisplayPrimariesParameters, + BalanceModeUserWhiteParameters, CameraSensorParameters, ColorParameters, MonoChromaticParameters, @@ -1174,7 +1176,7 @@ class BalanceModeUserWhite: def __init__( self, balance_mode_user_white: camera_sensor_pb2.SensorCameraBalanceModeUserwhite, - default_values: bool = True, + default_parameters: Union[None, BalanceModeUserWhiteParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -1182,11 +1184,12 @@ def __init__( raise RuntimeError(msg) self._balance_mode_user_white = balance_mode_user_white - if default_values: + if default_parameters: # Default values - self.red_gain = SENSOR.CAMERASENSOR.GAIN - self.green_gain = SENSOR.CAMERASENSOR.GAIN - self.blue_gain = SENSOR.CAMERASENSOR.GAIN + self._balance_mode_user_white.SetInParent() + self.red_gain = default_parameters.red_gain + self.green_gain = default_parameters.green_gain + self.blue_gain = default_parameters.blue_gain @property def red_gain(self) -> float: @@ -1286,7 +1289,7 @@ class BalanceModeDisplayPrimaries: def __init__( self, balance_mode_display: camera_sensor_pb2.SensorCameraBalanceModeDisplay, - default_values: bool = True, + default_parameters: Union[None, BalanceModeDisplayPrimariesParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -1297,9 +1300,12 @@ def __init__( self._balance_mode_display = balance_mode_display - if default_values: + if default_parameters: # Default values self._balance_mode_display.SetInParent() + self.red_display_file_uri = default_parameters.red_display_file_uri + self.green_display_file_uri = default_parameters.green_display_file_uri + self.blue_display_file_uri = default_parameters.blue_display_file_uri @property def red_display_file_uri(self) -> str: @@ -1370,7 +1376,7 @@ def blue_display_file_uri(self, uri: Union[str, Path]): def __init__( self, mode_color: camera_sensor_pb2.SensorCameraColorModeColor, - default_values: bool = True, + default_parameters: Union[None, ColorParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -1381,9 +1387,29 @@ def __init__( # Attribute gathering more complex camera balance mode self._mode = None - if default_values: + if default_parameters: # Default values - self.set_balance_mode_none() + if isinstance(default_parameters.balance_mode, BalanceModeUserWhiteParameters): + self._mode = SensorCamera.Photometric.Color.BalanceModeUserWhite( + balance_mode_user_white=self._mode_color.balance_mode_userwhite, + default_parameters=default_parameters.balance_mode, + stable_ctr=True, + ) + elif isinstance( + default_parameters.balance_mode, BalanceModeDisplayPrimariesParameters + ): + self._mode = SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries( + balance_mode_display=self._mode_color.balance_mode_display, + default_parameters=default_parameters.balance_mode, + stable_ctr=True, + ) + elif default_parameters.balance_mode == "grey_world": + self.set_balance_mode_grey_world() + elif default_parameters.balance_mode == "none": + self.set_balance_mode_none() + self.red_spectrum_file_uri = default_parameters.red_spectrum_file_uri + self.green_spectrum_file_uri = default_parameters.green_spectrum_file_uri + self.blue_spectrum_file_uri = default_parameters.blue_spectrum_file_uri @property def red_spectrum_file_uri(self) -> str: @@ -1503,7 +1529,7 @@ def set_balance_mode_user_white( # Happens in case of project created via load of speos file self._mode = SensorCamera.Photometric.Color.BalanceModeUserWhite( balance_mode_user_white=self._mode_color.balance_mode_userwhite, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance( @@ -1512,6 +1538,7 @@ def set_balance_mode_user_white( # if the _mode is not BalanceModeUserWhite then we create a new type. self._mode = SensorCamera.Photometric.Color.BalanceModeUserWhite( balance_mode_user_white=self._mode_color.balance_mode_userwhite, + default_parameters=BalanceModeUserWhiteParameters(), stable_ctr=True, ) elif ( @@ -1541,7 +1568,7 @@ def set_balance_mode_display_primaries( # Happens in case of project created via load of speos file self._mode = SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries( balance_mode_display=self._mode_color.balance_mode_display, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance( @@ -1550,6 +1577,7 @@ def set_balance_mode_display_primaries( # if the _mode is not BalanceModeDisplayPrimaries then we create a new type. self._mode = SensorCamera.Photometric.Color.BalanceModeDisplayPrimaries( balance_mode_display=self._mode_color.balance_mode_display, + default_parameters=BalanceModeDisplayPrimariesParameters(), stable_ctr=True, ) elif self._mode._balance_mode_display is not self._mode_color.balance_mode_display: @@ -1602,7 +1630,11 @@ def __init__( if isinstance(default_parameters.color_mode, MonoChromaticParameters): self.set_mode_monochromatic(default_parameters.color_mode.sensitivity) elif isinstance(default_parameters.color_mode, ColorParameters): - pass + self._mode = SensorCamera.Photometric.Color( + mode_color=self._mode_photometric.color_mode_color, + default_parameters=default_parameters.color_mode, + stable_ctr=True, + ) elif default_parameters is None: self._wavelengths_range = SensorCamera.WavelengthsRange( wavelengths_range=self._mode_photometric.wavelengths_range, From 23141f4952fca41faef2af8202b69e9263bf3492 Mon Sep 17 00:00:00 2001 From: sthoene Date: Fri, 19 Sep 2025 17:26:25 +0200 Subject: [PATCH 35/47] refactor irradiance sensor part 2 --- src/ansys/speos/core/generic/constants.py | 116 ++++++++-- src/ansys/speos/core/project.py | 4 +- src/ansys/speos/core/sensor.py | 268 +++++++++++++++------- 3 files changed, 279 insertions(+), 109 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 508e64bd0..02078d188 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -28,8 +28,6 @@ from pathlib import Path from typing import Union -from ansys.speos.core import GeoRef, body, face, part - DEFAULT_HOST: str = "localhost" """Default host used by Speos RPC server and client """ DEFAULT_PORT: str = "50098" @@ -50,8 +48,8 @@ @dataclass -class WavelengthsRange: - """Wavelength constants.""" +class WavelengthsRangeParameters: + """Wavelength parameters.""" start: int = 400 """Wavelength start value.""" @@ -62,8 +60,8 @@ class WavelengthsRange: @dataclass -class Dimensions: - """Dimension Constants.""" +class DimensionsParameters: + """Dimension Parameters.""" x_start: float = -50 """Lower bound x axis.""" @@ -102,7 +100,7 @@ class SequenceTypes(str, Enum): @dataclass -class LayerBySequence: +class LayerBySequenceParameters: """Layer separation type Parameters for Sequence separation.""" maximum_nb_of_sequence: int = 10 @@ -112,17 +110,25 @@ class LayerBySequence: @dataclass -class LayerByFace: +class GeometryLayerParameters: + """Geometry layer parameters.""" + + name: str + geometry: list + + +@dataclass +class LayerByFaceParameters: """Layer separation type Parameters for Face separation.""" - geometries: list[list[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] = None + geometries: list[GeometryLayerParameters] = None sca_filtering_types: Union[ SCAFilteringTypes.intersected_one_time, SCAFilteringTypes.last_impact ] = SCAFilteringTypes.last_impact @dataclass -class LayerbyIncidenceAngle: +class LayerByIncidenceAngleParameters: """Layer separation type Parameters for Incidence angle separation.""" incidence_sampling: int = 9 @@ -137,7 +143,7 @@ class PngBits(str, Enum): png_16 = "png_16" -class ColorBalanceMode(str, Enum): +class ColorBalanceModeTypes(str, Enum): """Color Balance Mode types without parameters.""" none = "none" @@ -173,11 +179,11 @@ class ColorParameters: """Color mode Camera Parameter.""" balance_mode: Union[ - ColorBalanceMode.none, - ColorBalanceMode.grey_world, + ColorBalanceModeTypes.none, + ColorBalanceModeTypes.grey_world, BalanceModeUserWhiteParameters, BalanceModeDisplayPrimariesParameters, - ] = ColorBalanceMode.none + ] = ColorBalanceModeTypes.none """Camera Balance mode.""" red_spectrum_file_uri: str = "" """Path to sensitivity spectrum of red Channel.""" @@ -205,7 +211,7 @@ class PhotometricCameraParameters: """Layer separation parameter.""" png_bits: Union[PngBits.png_08, PngBits.png_10, PngBits.png_12, PngBits.png_16] = PngBits.png_16 """PNG bit resolution of the Camera Sensor.""" - wavelength_range = WavelengthsRange() + wavelength_range = WavelengthsRangeParameters() """Wavelength range of the Camera Sensor.""" ACQUISITION_INTEGRATION: float = 0.01 """Integration Time value for the Camera Sensor.""" @@ -221,7 +227,7 @@ class CameraSensorParameters: sensor_type_parameters: Union[None, PhotometricCameraParameters] = PhotometricCameraParameters() """Camera sensor type None means geometric sensor""" - axis_system: list[float] = field(default_factory=lambda: [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]) + axis_system: list[float] = field(default_factory=lambda: ORIGIN) """Location of the sensor Origin""" focal_length: float = 5 """Default focal length of the Camera Sensor.""" @@ -238,6 +244,80 @@ class CameraSensorParameters: height: float = 5.0 """Default height of the camera chip.""" trajectory_fil_uri: Union[str, Path] = "" + """Trajectory file information.""" + lxp_path_number: Union[None, int] = None + + +@dataclass +class ColorimetricParameters: + """Colorimetric settings of the Sensor.""" + + wavelength_range = WavelengthsRangeParameters() + """Wavelength range of the Sensor.""" + + +@dataclass +class SpectralParameters: + """Colorimetric settings of the Sensor.""" + + wavelength_range = WavelengthsRangeParameters() + """Wavelength range of the Sensor.""" + + +class IntegrationTypes(str, Enum): + """Integration types without parameters.""" + + planar = "planar" + radial = "radial" + hemispherical = "hemispherical" + cylindrical = "cylindrical" + semi_cylindrical = "semi_cylindrical" + + +class RayfileTypes(str, Enum): + """Rayfile types without parameters.""" + + none = "none" + classic = "classic" + polarization = "polarization" + tm25 = "tm25" + tm25_no_polarization = "tm25_no_polarization" + + +class SensorTypes(str, Enum): + """Sensor types without parameters.""" + + photometric = "photometric" + radiometric = "radiometric" + + +@dataclass +class IrradianceSensorParameters: + """Irradiance Sensor Parameters.""" + + dimensions: DimensionsParameters = DimensionsParameters() + """Dimensions of the sensor.""" + axis_system: list[float] = field(default_factory=lambda: ORIGIN) + """Position of the sensor.""" + sensor_type: Union[ + SensorTypes.photometric, ColorimetricParameters, SpectralParameters, SensorTypes.radiometric + ] = SensorTypes.photometric + """Type of the sensor.""" + integration_type: Union[IntegrationTypes] = IntegrationTypes.planar + """Integration type of the sensor.""" + integration_direction: Union[None, list[float]] = None + """Integration direction of the sensor.""" + rayfile_type: Union[RayfileTypes] = RayfileTypes.none + """Type of rayfile stored by the sensor.""" + layer_type: Union[ + LayerTypes, + LayerByFaceParameters, + LayerBySequenceParameters, + LayerByIncidenceAngleParameters, + ] = LayerTypes.none + """Type of layer separation used by the sensor.""" + outpath_face_geometry: list = None + """Outpath face used by the sensor""" @dataclass(frozen=True) @@ -252,8 +332,6 @@ class RadianceSensor: class SENSOR: """Constant class for Sensors.""" - WAVELENGTHSRANGE = WavelengthsRange() - DIMENSIONS = Dimensions() - LAYERTYPES = LayerTypes() + WAVELENGTHSRANGE = WavelengthsRangeParameters() CAMERASENSOR = "" RADIANCESENSOR = RadianceSensor() diff --git a/src/ansys/speos/core/project.py b/src/ansys/speos/core/project.py index bbb1e88fe..d7dd7b4be 100644 --- a/src/ansys/speos/core/project.py +++ b/src/ansys/speos/core/project.py @@ -827,7 +827,7 @@ def _fill_features(self): project=self, name=ssr_inst.name, sensor_instance=ssr_inst, - default_values=False, + default_parameters=None, ) elif ssr_inst.HasField("radiance_properties"): ssr_feat = SensorRadiance( @@ -841,7 +841,7 @@ def _fill_features(self): project=self, name=ssr_inst.name, sensor_instance=ssr_inst, - default_values=False, + default_parameters=None, ) elif ssr_inst.HasField("irradiance_3d_properties"): ssr_feat = Sensor3DIrradiance( diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 1de520bca..0cafb5037 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -26,7 +26,7 @@ from difflib import SequenceMatcher from pathlib import Path -from typing import List, Mapping, Optional, Union +from typing import Mapping, Optional, Union import uuid import warnings @@ -43,10 +43,16 @@ BalanceModeDisplayPrimariesParameters, BalanceModeUserWhiteParameters, CameraSensorParameters, + ColorimetricParameters, ColorParameters, + IrradianceSensorParameters, + LayerByFaceParameters, + LayerByIncidenceAngleParameters, + LayerBySequenceParameters, MonoChromaticParameters, PhotometricCameraParameters, - WavelengthsRange, + SpectralParameters, + WavelengthsRangeParameters, ) import ansys.speos.core.generic.general_methods as general_methods from ansys.speos.core.generic.visualization_methods import _VisualData, local2absolute @@ -122,7 +128,7 @@ def __init__( self.reset() @property - def lxp_path_number(self) -> int: + def lxp_path_number(self) -> Union[None, int]: """Number of LXP rays simulated for the Sensor. Returns @@ -171,7 +177,7 @@ class WavelengthsRange: def __init__( self, wavelengths_range: Union[common_pb2.WavelengthsRange, sensor_pb2.TypeColorimetric], - default_parameters: Union[None, WavelengthsRange] = None, + default_parameters: Union[None, WavelengthsRangeParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -467,7 +473,7 @@ class Colorimetric: ---------- sensor_type_colorimetric : ansys.api.speos.sensor.v1.common_pb2.SensorTypeColorimetric SensorTypeColorimetric protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -481,7 +487,7 @@ class Colorimetric: def __init__( self, sensor_type_colorimetric: common_pb2.SensorTypeColorimetric, - default_values: bool = True, + default_parameters: Union[None, ColorimetricParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -489,16 +495,19 @@ def __init__( raise RuntimeError(msg) self._sensor_type_colorimetric = sensor_type_colorimetric - # Attribute to keep track of wavelength range object - self._wavelengths_range = BaseSensor.WavelengthsRange( - wavelengths_range=self._sensor_type_colorimetric.wavelengths_range, - default_values=default_values, - stable_ctr=stable_ctr, - ) - - if default_values: + if default_parameters: # Default values - self.set_wavelengths_range() + self._wavelengths_range = BaseSensor.WavelengthsRange( + wavelengths_range=self._sensor_type_colorimetric.wavelengths_range, + default_parameters=default_parameters.wavelength_range, + stable_ctr=stable_ctr, + ) + else: + self._wavelengths_range = BaseSensor.WavelengthsRange( + wavelengths_range=self._sensor_type_colorimetric.wavelengths_range, + default_parameters=None, + stable_ctr=stable_ctr, + ) def set_wavelengths_range(self) -> BaseSensor.WavelengthsRange: """Set the range of wavelengths. @@ -543,7 +552,7 @@ class Spectral: def __init__( self, sensor_type_spectral: common_pb2.SensorTypeSpectral, - default_values: bool = True, + default_parameters: Union[None, SpectralParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -551,16 +560,19 @@ def __init__( raise RuntimeError(msg) self._sensor_type_spectral = sensor_type_spectral - # Attribute to keep track of wavelength range object - self._wavelengths_range = BaseSensor.WavelengthsRange( - wavelengths_range=self._sensor_type_spectral.wavelengths_range, - default_values=default_values, - stable_ctr=stable_ctr, - ) - - if default_values: + if default_parameters: # Default values - self.set_wavelengths_range() + self._wavelengths_range = BaseSensor.WavelengthsRange( + wavelengths_range=self._sensor_type_spectral.wavelengths_range, + default_parameters=default_parameters.wavelength_range, + stable_ctr=stable_ctr, + ) + else: + self._wavelengths_range = BaseSensor.WavelengthsRange( + wavelengths_range=self._sensor_type_spectral.wavelengths_range, + default_parameters=None, + stable_ctr=stable_ctr, + ) def set_wavelengths_range(self) -> BaseSensor.WavelengthsRange: """Set the range of wavelengths. @@ -586,7 +598,7 @@ class FaceLayer: ---------- name : str Name of the layer. - geometries : List[ansys.speos.core.geo_ref.GeoRef] + geometries : list[ansys.speos.core.geo_ref.GeoRef] List of geometries included in this layer. """ @@ -637,7 +649,7 @@ class LayerTypeFace: layer_type_face : \ ansys.api.speos.scene.v2.scene_pb2.Scene.SensorInstance.LayerTypeFace LayerTypeFace protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -651,7 +663,7 @@ class LayerTypeFace: def __init__( self, layer_type_face: ProtoScene.SensorInstance.LayerTypeFace, - default_values: bool = True, + default_parameters: Union[None, LayerByFaceParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -660,9 +672,16 @@ def __init__( self._layer_type_face = layer_type_face - if default_values: + if default_parameters: # Default values - self.set_sca_filtering_mode_last_impact() + match default_parameters.sca_filtering_types: + case "last_impact": + self.set_sca_filtering_mode_last_impact() + case "intersected_one_time": + self.set_sca_filtering_mode_intersected_one_time() + if default_parameters.geometries: + for item in default_parameters.geometries: + self.layers.append(BaseSensor.FaceLayer(item.name, item.geometry)) def set_sca_filtering_mode_intersected_one_time( self, @@ -709,12 +728,12 @@ def layers(self) -> list[BaseSensor.FaceLayer]: return layer_data @layers.setter - def layers(self, values: List[BaseSensor.FaceLayer]): + def layers(self, values: list[BaseSensor.FaceLayer]): """Set the layers. Parameters ---------- - values : List[ansys.speos.core.sensor.BaseSensor.FaceLayer] + values : list[ansys.speos.core.sensor.BaseSensor.FaceLayer] List of layers """ my_list = [ @@ -740,7 +759,7 @@ class LayerTypeSequence: layer_type_sequence : \ ansys.api.speos.scene.v2.scene_pb2.Scene.SensorInstance.LayerTypeSequence LayerTypeSequence protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -754,7 +773,7 @@ class LayerTypeSequence: def __init__( self, layer_type_sequence: ProtoScene.SensorInstance.LayerTypeSequence, - default_values: bool = True, + default_parameters: Union[None, LayerBySequenceParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -763,10 +782,14 @@ def __init__( self._layer_type_sequence = layer_type_sequence - if default_values: + if default_parameters: # Default values - self.maximum_nb_of_sequence = SENSOR.LAYERTYPES.MAXIMUM_NB_OF_SEQUENCE - self.set_define_sequence_per_geometries() + self.maximum_nb_of_sequence = default_parameters.maximum_nb_of_sequence + match default_parameters.sequence_type: + case "by_face": + self.set_define_sequence_per_faces() + case "by_geometry": + self.set_define_sequence_per_geometries() @property def maximum_nb_of_sequence(self) -> int: @@ -831,7 +854,7 @@ class LayerTypeIncidenceAngle: layer_type_incidence_angle : \ ansys.api.speos.scene.v2.scene_pb2.Scene.SensorInstance.LayerTypeIncidenceAngle LayerTypeIncidenceAngle protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -845,7 +868,7 @@ class LayerTypeIncidenceAngle: def __init__( self, layer_type_incidence_angle: ProtoScene.SensorInstance.LayerTypeIncidenceAngle, - default_values: bool = True, + default_parameters: Union[None, LayerByIncidenceAngleParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -854,9 +877,9 @@ def __init__( self._layer_type_incidence_angle = layer_type_incidence_angle - if default_values: + if default_parameters: # Default values - self.sampling = SENSOR.LAYERTYPES.INCIDENCE_SAMPLING + self.sampling = default_parameters.incidence_sampling @property def sampling(self) -> BaseSensor.LayerTypeIncidenceAngle: @@ -1940,6 +1963,7 @@ def __init__( self.width = default_parameters.width self.height = default_parameters.height self.axis_system = default_parameters.axis_system + self.lxp_path_number = default_parameters.lxp_path_number if isinstance(default_parameters.sensor_type_parameters, PhotometricCameraParameters): self._type = SensorCamera.Photometric( @@ -2254,25 +2278,25 @@ def height(self, value: float): self._sensor_template.camera_sensor_template.height = value @property - def axis_system(self) -> List[float]: + def axis_system(self) -> list[float]: """The position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. Returns ------- - List[float] + list[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. """ return self._sensor_instance.camera_properties.axis_system @axis_system.setter - def axis_system(self, axis_system: List[float]): + def axis_system(self, axis_system: list[float]): """Position of the sensor. Parameters ---------- - axis_system : List[float] + axis_system : list[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ @@ -2387,7 +2411,7 @@ class SensorIrradiance(BaseSensor): sensor_instance : ansys.api.speos.scene.v2.scene_pb2.Scene.SensorInstance, optional Sensor instance to provide if the feature does not has to be created from scratch By default, ``None``, means that the feature is created from scratch by default. - default_values : bool + default_parameters : bool Uses default values when True. By default, ``True``. """ @@ -2399,7 +2423,7 @@ def __init__( description: str = "", metadata: Optional[Mapping[str, str]] = None, sensor_instance: Optional[ProtoScene.SensorInstance] = None, - default_values: bool = True, + default_parameters: Union[None, IrradianceSensorParameters] = None, ) -> None: if metadata is None: metadata = {} @@ -2418,19 +2442,87 @@ def __init__( # Attribute gathering more complex layer type self._layer_type = None - # Attribute to keep track of sensor dimensions object - self._sensor_dimensions = self.Dimensions( - sensor_dimensions=self._sensor_template.irradiance_sensor_template.dimensions, - default_values=default_values, - stable_ctr=True, - ) - - if default_values: + if sensor_instance is None: + if default_parameters is None: + default_parameters = IrradianceSensorParameters() # Default values template - self.set_type_photometric().set_illuminance_type_planar() + + if isinstance(default_parameters.sensor_type, ColorimetricParameters): + self._type = BaseSensor.Colorimetric( + sensor_type_colorimetric=self._sensor_template.irradiance_sensor_template.sensor_type_colorimetric, + default_parameters=default_parameters.sensor_type, + stable_ctr=True, + ) + elif isinstance(default_parameters.sensor_type, SpectralParameters): + self._type = BaseSensor.Spectral( + sensor_type_spectral=self._sensor_template.irradiance_sensor_template.sensor_type_spectral, + default_parameters=default_parameters.sensor_type, + stable_ctr=True, + ) + elif default_parameters == "radiometric": + self.set_type_radiometric() + elif default_parameters == "photometric": + self.set_type_photometric() + + match default_parameters.integration_type: + case "planar": + self.set_illuminance_type_planar() + self.integration_direction = default_parameters.integration_direction + case "radial": + self.set_illuminance_type_radial() + case "hemispherical": + self.set_illuminance_type_hemispherical() + case "cylindrical": + self.set_illuminance_type_cylindrical() + case "semi_cylindrical": + self.set_illuminance_type_semi_cylindrical() + self.integration_direction = default_parameters.integration_direction + + match default_parameters.rayfile_type: + case "none": + self.set_ray_file_type_none() + case "classic": + self.set_ray_file_type_classic() + case "polarization": + self.set_ray_file_type_polarization() + case "tm25": + self.set_ray_file_type_tm25() + case "tm25_no_polarization": + self.set_ray_file_type_tm25_no_polarization() + + if default_parameters.layer_type == "none": + self.set_layer_type_none() + elif default_parameters.layer_type == "by_source": + self.set_layer_type_source() + elif default_parameters.layer_type == "by_polarization": + self.set_layer_type_polarization() + elif isinstance(default_parameters.layer_type, LayerByFaceParameters): + self._layer_type = BaseSensor.LayerTypeFace( + layer_type_face=self._sensor_instance.irradiance_properties.layer_type_face, + default_parameters=default_parameters.layer_type, + stable_ctr=True, + ) + elif isinstance(default_parameters.layer_type, LayerBySequenceParameters): + self._layer_type = BaseSensor.LayerTypeSequence( + layer_type_sequence=self._sensor_instance.irradiance_properties.layer_type_sequence, + default_parameters=default_parameters.layer_type, + stable_ctr=True, + ) + elif isinstance(default_parameters.layer_type, LayerByIncidenceAngleParameters): + self._layer_type = BaseSensor.LayerTypeIncidenceAngle( + layer_type_incidence_angle=self._sensor_instance.irradiance_properties.layer_type_incidence_angle, + default_parameters=default_parameters.layer_type, + stable_ctr=True, + ) # Default values properties - self.axis_system = ORIGIN - self.set_ray_file_type_none().set_layer_type_none() + self.axis_system = default_parameters.axis_system + self.output_face_geometries = default_parameters.outpath_face_geometry + else: + self._sensor_dimensions = self.Dimensions( + sensor_dimensions=self._sensor_template.irradiance_sensor_template.dimensions, + default_parameters=None, + stable_ctr=True, + ) @property def visual_data(self) -> _VisualData: @@ -2618,7 +2710,7 @@ def set_type_colorimetric(self) -> BaseSensor.Colorimetric: # Happens in case of project created via load of speos file self._type = BaseSensor.Colorimetric( sensor_type_colorimetric=self._sensor_template.irradiance_sensor_template.sensor_type_colorimetric, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, BaseSensor.Colorimetric): @@ -2702,18 +2794,18 @@ def integration_direction(self): Returns ------- - List[float] + list[float] Sensor global integration direction [x,y,z] """ return self._sensor_instance.irradiance_properties.integration_direction @integration_direction.setter - def integration_direction(self, value: List[float]): + def integration_direction(self, value: list[float]): """Set integration direction. Parameters ---------- - value : List[float] + value : list[float] Sensor global integration direction [x,y,z] """ if not value: @@ -2737,7 +2829,7 @@ def set_illuminance_type_planar(self) -> SensorIrradiance: Parameters ---------- - integration_direction : List[float], optional + integration_direction : list[float], optional Sensor global integration direction [x,y,z]. The integration direction must be set in the anti-rays direction to integrate their signal. @@ -2804,25 +2896,25 @@ def set_illuminance_type_semi_cylindrical(self) -> SensorIrradiance: return self @property - def axis_system(self) -> List[float]: + def axis_system(self) -> list[float]: """Position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. Returns ------- - List[float] + list[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. """ return self._sensor_instance.irradiance_properties.axis_system @axis_system.setter - def axis_system(self, axis_system: List[float]): + def axis_system(self, axis_system: list[float]): """Position of the sensor. Parameters ---------- - axis_system : List[float] + axis_system : list[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ @@ -2934,7 +3026,7 @@ def set_layer_type_face(self) -> BaseSensor.LayerTypeFace: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeFace( layer_type_face=self._sensor_instance.irradiance_properties.layer_type_face, - default_values=False, + default_parameters=False, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeFace): @@ -2967,7 +3059,7 @@ def set_layer_type_sequence(self) -> BaseSensor.LayerTypeSequence: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeSequence( layer_type_sequence=self._sensor_instance.irradiance_properties.layer_type_sequence, - default_values=False, + default_parameters=False, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeSequence): @@ -3014,7 +3106,7 @@ def set_layer_type_incidence_angle( # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeIncidenceAngle( layer_type_incidence_angle=self._sensor_instance.irradiance_properties.layer_type_incidence_angle, - default_values=False, + default_parameters=False, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeIncidenceAngle): @@ -3039,8 +3131,8 @@ def output_face_geometries(self) -> SensorIrradiance: Parameters ---------- - geometries : List[ansys.speos.core.geo_ref.GeoRef] - List of geometries that will be considered as output faces. + geometries : list[ansys.speos.core.geo_ref.GeoRef] + list of geometries that will be considered as output faces. By default, ``[]``, ie no output faces. Returns @@ -3054,13 +3146,13 @@ def output_face_geometries(self) -> SensorIrradiance: @output_face_geometries.setter def output_face_geometries( self, - geometries: Optional[List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] = None, + geometries: Optional[list[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]]] = None, ) -> SensorIrradiance: """Select output faces for inverse simulation optimization. Parameters ---------- - geometries : List[ansys.speos.core.geo_ref.GeoRef] + geometries : list[ansys.speos.core.geo_ref.GeoRef] List of geometries that will be considered as output faces. By default, ``[]``, ie no output faces. @@ -3339,7 +3431,7 @@ def set_type_colorimetric(self) -> BaseSensor.Colorimetric: # Happens in case of project created via load of speos file self._type = BaseSensor.Colorimetric( sensor_type_colorimetric=self._sensor_template.radiance_sensor_template.sensor_type_colorimetric, - default_values=False, + default_parameters=False, stable_ctr=True, ) elif not isinstance(self._type, BaseSensor.Colorimetric): @@ -3459,25 +3551,25 @@ def integration_angle(self, value: float) -> SensorRadiance: self._sensor_template.radiance_sensor_template.integration_angle = value @property - def axis_system(self) -> List[float]: + def axis_system(self) -> list[float]: """Position of the sensor. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. Returns ------- - List[float] + list[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. """ return self._sensor_instance.radiance_properties.axis_system @axis_system.setter - def axis_system(self, axis_system: List[float]): + def axis_system(self, axis_system: list[float]): """Position of the sensor. Parameters ---------- - axis_system : List[float] + axis_system : list[float] Position of the sensor [Ox Oy Oz Xx Xy Xz Yx Yy Yz Zx Zy Zz]. By default, ``[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]``. """ @@ -3494,14 +3586,14 @@ def observer_point(self) -> SensorRadiance: Returns ------- - Union[None, List[float]] + Union[None, list[float]] Position of the observer point [Ox Oy Oz], None means that the focal length is used. """ return self._sensor_instance.radiance_properties.observer_point @observer_point.setter - def observer_point(self, value: List[float]): + def observer_point(self, value: list[float]): """Position of the observer point. This is optional, because the focal length is used by default. @@ -3509,7 +3601,7 @@ def observer_point(self, value: List[float]): Parameters ---------- - value : List[float] + value : list[float] Position of the observer point [Ox Oy Oz]. By default, ``None``. None means that the focal length is used. """ @@ -3558,7 +3650,7 @@ def set_layer_type_face(self) -> BaseSensor.LayerTypeFace: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeFace( layer_type_face=self._sensor_instance.radiance_properties.layer_type_face, - default_values=False, + default_parameters=False, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeFace): @@ -3591,7 +3683,7 @@ def set_layer_type_sequence(self) -> BaseSensor.LayerTypeSequence: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeSequence( layer_type_sequence=self._sensor_instance.radiance_properties.layer_type_sequence, - default_values=False, + default_parameters=False, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeSequence): @@ -4246,25 +4338,25 @@ def set_layer_type_source(self) -> Sensor3DIrradiance: return self @property - def geometries(self) -> List[str]: + def geometries(self) -> list[str]: """Geometry faces/bodies to be defined with 3D irradiance sensor. Returns ------- - List[str] + list[str] List of geometries that will be considered as Sensor """ return self._sensor_instance.irradiance_3d_properties.geometries.geo_paths @geometries.setter def geometries( - self, geometries: List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]] + self, geometries: list[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]] ) -> Sensor3DIrradiance: """Select geometry faces to be defined with 3D irradiance sensor. Parameters ---------- - geometries : List[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]] + geometries : list[Union[GeoRef, body.Body, face.Face, part.Part.SubPart]] List of geometries that will be considered as Sensor """ geo_paths = [] From df19c1bc32278f33328f3493db4fa3a1feeff795 Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 22 Sep 2025 11:56:51 +0200 Subject: [PATCH 36/47] refactor irradiance sensor part 3 --- src/ansys/speos/core/sensor.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 0cafb5037..4169e32fe 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -45,6 +45,7 @@ CameraSensorParameters, ColorimetricParameters, ColorParameters, + DimensionsParameters, IrradianceSensorParameters, LayerByFaceParameters, LayerByIncidenceAngleParameters, @@ -301,7 +302,7 @@ class Dimensions: def __init__( self, sensor_dimensions: common_pb2.SensorDimensions, - default_values: bool = True, + default_parameters: Union[None, DimensionsParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -309,14 +310,14 @@ def __init__( raise RuntimeError(msg) self._sensor_dimensions = sensor_dimensions - if default_values: + if default_parameters: # Default values - self.x_start = SENSOR.DIMENSIONS.X_START - self.y_start = SENSOR.DIMENSIONS.Y_START - self.x_end = SENSOR.DIMENSIONS.X_END - self.y_end = SENSOR.DIMENSIONS.Y_END - self.x_sampling = SENSOR.DIMENSIONS.X_SAMPLING - self.y_sampling = SENSOR.DIMENSIONS.Y_SAMPLING + self.x_start = default_parameters.x_start + self.y_start = default_parameters.y_start + self.x_end = default_parameters.x_end + self.y_end = default_parameters.y_end + self.x_sampling = default_parameters.x_sampling + self.y_sampling = default_parameters.y_sampling @property def x_start(self) -> float: @@ -2760,13 +2761,14 @@ def set_type_spectral(self) -> BaseSensor.Spectral: # Happens in case of project created via load of speos file self._type = BaseSensor.Spectral( sensor_type_spectral=self._sensor_template.irradiance_sensor_template.sensor_type_spectral, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, BaseSensor.Spectral): # if the _type is not Spectral then we create a new type. self._type = BaseSensor.Spectral( sensor_type_spectral=self._sensor_template.irradiance_sensor_template.sensor_type_spectral, + default_parameters=SpectralParameters(), stable_ctr=True, ) elif ( @@ -3026,13 +3028,14 @@ def set_layer_type_face(self) -> BaseSensor.LayerTypeFace: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeFace( layer_type_face=self._sensor_instance.irradiance_properties.layer_type_face, - default_parameters=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeFace): # if the _layer_type is not LayerTypeFace then we create a new type. self._layer_type = BaseSensor.LayerTypeFace( layer_type_face=self._sensor_instance.irradiance_properties.layer_type_face, + default_parameters=LayerByFaceParameters(), stable_ctr=True, ) elif ( @@ -3059,13 +3062,14 @@ def set_layer_type_sequence(self) -> BaseSensor.LayerTypeSequence: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeSequence( layer_type_sequence=self._sensor_instance.irradiance_properties.layer_type_sequence, - default_parameters=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeSequence): # if the _type is not LayerTypeSequence then we create a new type. self._layer_type = BaseSensor.LayerTypeSequence( layer_type_sequence=self._sensor_instance.irradiance_properties.layer_type_sequence, + default_parameters=LayerBySequenceParameters(), stable_ctr=True, ) elif ( @@ -3106,13 +3110,14 @@ def set_layer_type_incidence_angle( # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeIncidenceAngle( layer_type_incidence_angle=self._sensor_instance.irradiance_properties.layer_type_incidence_angle, - default_parameters=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeIncidenceAngle): # if the _layer_type is not LayerTypeIncidenceAngle then we create a new type. self._layer_type = BaseSensor.LayerTypeIncidenceAngle( layer_type_incidence_angle=self._sensor_instance.irradiance_properties.layer_type_incidence_angle, + default_parameters=LayerByIncidenceAngleParameters(), stable_ctr=True, ) elif ( From 117363b166825ebd0ae258fe2a54b0ac759f15b2 Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 23 Sep 2025 12:30:24 +0200 Subject: [PATCH 37/47] refactor sensors --- src/ansys/speos/core/generic/constants.py | 67 +++++- src/ansys/speos/core/project.py | 4 +- src/ansys/speos/core/sensor.py | 240 ++++++++++++++++------ 3 files changed, 233 insertions(+), 78 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 02078d188..901529f98 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -291,6 +291,18 @@ class SensorTypes(str, Enum): radiometric = "radiometric" +@dataclass +class MeasuresParameters: + """Measurements for 3d Irradiance Sensor.""" + + reflection: bool = True + """Reflection measure activation state.""" + transmission: bool = True + """Transmission measure activation state.""" + absorption: bool = True + """Ansorption measure activation state.""" + + @dataclass class IrradianceSensorParameters: """Irradiance Sensor Parameters.""" @@ -320,18 +332,53 @@ class IrradianceSensorParameters: """Outpath face used by the sensor""" -@dataclass(frozen=True) -class RadianceSensor: +@dataclass +class RadianceSensorParameters: """Radiance Sensor Constants.""" - FOCAL_LENGTH = 250 - INTEGRATION_ANGLE = 5 + dimensions: DimensionsParameters = DimensionsParameters() + """Dimensions of the sensor.""" + axis_system: list[float] = field(default_factory=lambda: ORIGIN) + """Position of the sensor.""" + sensor_type: Union[ + SensorTypes.photometric, ColorimetricParameters, SpectralParameters, SensorTypes.radiometric + ] = SensorTypes.photometric + """Type of the sensor.""" + focal_length: float = 250.0 + """Distance between observer point and sensor and axis-system, + will be ignored if observer is used.""" + integration_angle: float = 5 + """Integration angle.""" + observer: Union[None, list[float]] = None + """The position of the observer point.""" + layer_type: Union[ + LayerTypes.none, + LayerTypes.by_source, + LayerByFaceParameters, + LayerBySequenceParameters, + ] = LayerTypes.none + """Type of layer separation used by the sensor.""" + +@dataclass +class Irradiance3DSensorParameters: + """Parameters class for 3D Irradiance Sensor.""" -@dataclass(frozen=True) -class SENSOR: - """Constant class for Sensors.""" + sensor_type: Union[SensorTypes.photometric, ColorimetricParameters, SensorTypes.radiometric] = ( + SensorTypes.photometric + ) + """Type of the sensor.""" + measures = MeasuresParameters() + """Measurement activation state.""" + integration_type: Union[IntegrationTypes.planar, IntegrationTypes.radial] = ( + IntegrationTypes.planar + ) + """Integration type.""" + rayfile_type: Union[RayfileTypes] = RayfileTypes.none + """Rayfile type stored.""" + layer_type: Union[LayerTypes.none, LayerTypes.by_source] = LayerTypes.none + """Layer separation type.""" + geometries: list = None + """Sensor geometry.""" - WAVELENGTHSRANGE = WavelengthsRangeParameters() - CAMERASENSOR = "" - RADIANCESENSOR = RadianceSensor() + pass diff --git a/src/ansys/speos/core/project.py b/src/ansys/speos/core/project.py index d7dd7b4be..4f92e3232 100644 --- a/src/ansys/speos/core/project.py +++ b/src/ansys/speos/core/project.py @@ -834,7 +834,7 @@ def _fill_features(self): project=self, name=ssr_inst.name, sensor_instance=ssr_inst, - default_values=False, + default_parameters=None, ) elif ssr_inst.HasField("camera_properties"): ssr_feat = SensorCamera( @@ -848,7 +848,7 @@ def _fill_features(self): project=self, name=ssr_inst.name, sensor_instance=ssr_inst, - default_values=False, + default_parameters=None, ) self._features.append(ssr_feat) diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 4169e32fe..08db461a5 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -38,20 +38,21 @@ import ansys.speos.core.body as body import ansys.speos.core.face as face from ansys.speos.core.generic.constants import ( - ORIGIN, - SENSOR, BalanceModeDisplayPrimariesParameters, BalanceModeUserWhiteParameters, CameraSensorParameters, ColorimetricParameters, ColorParameters, DimensionsParameters, + Irradiance3DSensorParameters, IrradianceSensorParameters, LayerByFaceParameters, LayerByIncidenceAngleParameters, LayerBySequenceParameters, + MeasuresParameters, MonoChromaticParameters, PhotometricCameraParameters, + RadianceSensorParameters, SpectralParameters, WavelengthsRangeParameters, ) @@ -3205,7 +3206,7 @@ class SensorRadiance(BaseSensor): sensor_instance : ansys.api.speos.scene.v2.scene_pb2.Scene.SensorInstance, optional Sensor instance to provide if the feature does not has to be created from scratch By default, ``None``, means that the feature is created from scratch by default. - default_values : bool + default_parameters : bool Uses default values when True. By default, ``True``. """ @@ -3217,7 +3218,7 @@ def __init__( description: str = "", metadata: Optional[Mapping[str, str]] = None, sensor_instance: Optional[ProtoScene.SensorInstance] = None, - default_values: bool = True, + default_parameters: Union[None, RadianceSensorParameters] = None, ) -> None: if metadata is None: metadata = {} @@ -3239,18 +3240,61 @@ def __init__( # Attribute to keep track of sensor dimensions object self._sensor_dimensions = self.Dimensions( sensor_dimensions=self._sensor_template.radiance_sensor_template.dimensions, - default_values=default_values, + default_parameters=None, stable_ctr=True, ) - - if default_values: + if sensor_instance is None: + if default_parameters is None: + default_parameters = RadianceSensorParameters() # Default values template - self.focal = SENSOR.RADIANCESENSOR.focal_length - self.integration_angle = SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE - self.set_type_photometric() - # Default values properties - self.axis_system = ORIGIN - self.set_layer_type_none() + self.focal = default_parameters.focal_length + self.integration_angle = default_parameters.integration_angle + self.axis_system = default_parameters.axis_system + self.observer_point = default_parameters.observer + self._sensor_dimensions = self.Dimensions( + sensor_dimensions=self._sensor_template.radiance_sensor_template.dimensions, + default_parameters=default_parameters.dimensions, + stable_ctr=True, + ) + if isinstance(default_parameters.sensor_type, ColorimetricParameters): + self._type = BaseSensor.Colorimetric( + sensor_type_colorimetric=self._sensor_template.radiance_sensor_template.sensor_type_colorimetric, + default_parameters=default_parameters.sensor_type, + stable_ctr=True, + ) + elif isinstance(default_parameters.sensor_type, SpectralParameters): + self._type = BaseSensor.Spectral( + sensor_type_spectral=self._sensor_template.radiance_sensor_template.sensor_type_spectral, + default_parameters=default_parameters.sensor_type, + stable_ctr=True, + ) + elif default_parameters == "radiometric": + self.set_type_radiometric() + elif default_parameters == "photometric": + self.set_type_photometric() + + if default_parameters.layer_type == "none": + self.set_layer_type_none() + elif default_parameters.layer_type == "by_source": + self.set_layer_type_source() + elif isinstance(default_parameters.layer_type, LayerByFaceParameters): + self._layer_type = BaseSensor.LayerTypeFace( + layer_type_face=self._sensor_instance.radiance_properties.layer_type_face, + default_parameters=default_parameters.layer_type, + stable_ctr=True, + ) + elif isinstance(default_parameters.layer_type, LayerBySequenceParameters): + self._layer_type = BaseSensor.LayerTypeSequence( + layer_type_sequence=self._sensor_instance.radiance_properties.layer_type_sequence, + default_parameters=default_parameters.layer_type, + stable_ctr=True, + ) + else: + self._sensor_dimensions = self.Dimensions( + sensor_dimensions=self._sensor_template.radiance_sensor_template.dimensions, + default_parameters=None, + stable_ctr=True, + ) @property def visual_data(self) -> _VisualData: @@ -3436,13 +3480,14 @@ def set_type_colorimetric(self) -> BaseSensor.Colorimetric: # Happens in case of project created via load of speos file self._type = BaseSensor.Colorimetric( sensor_type_colorimetric=self._sensor_template.radiance_sensor_template.sensor_type_colorimetric, - default_parameters=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, BaseSensor.Colorimetric): # if the _type is not Colorimetric then we create a new type. self._type = BaseSensor.Colorimetric( sensor_type_colorimetric=self._sensor_template.radiance_sensor_template.sensor_type_colorimetric, + default_parameters=ColorimetricParameters(), stable_ctr=True, ) elif ( @@ -3486,13 +3531,14 @@ def set_type_spectral(self) -> BaseSensor.Spectral: # Happens in case of project created via load of speos file self._type = BaseSensor.Spectral( sensor_type_spectral=self._sensor_template.radiance_sensor_template.sensor_type_spectral, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, BaseSensor.Spectral): # if the _type is not Spectral then we create a new type. self._type = BaseSensor.Spectral( sensor_type_spectral=self._sensor_template.radiance_sensor_template.sensor_type_spectral, + default_parameters=SpectralParameters(), stable_ctr=True, ) elif ( @@ -3655,13 +3701,14 @@ def set_layer_type_face(self) -> BaseSensor.LayerTypeFace: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeFace( layer_type_face=self._sensor_instance.radiance_properties.layer_type_face, - default_parameters=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeFace): # if the _layer_type is not LayerTypeFace then we create a new type. self._layer_type = BaseSensor.LayerTypeFace( layer_type_face=self._sensor_instance.radiance_properties.layer_type_face, + default_parameters=LayerByFaceParameters(), stable_ctr=True, ) elif ( @@ -3688,13 +3735,14 @@ def set_layer_type_sequence(self) -> BaseSensor.LayerTypeSequence: # Happens in case of project created via load of speos file self._layer_type = BaseSensor.LayerTypeSequence( layer_type_sequence=self._sensor_instance.radiance_properties.layer_type_sequence, - default_parameters=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._layer_type, BaseSensor.LayerTypeSequence): # if the _layer_type is not LayerTypeSequence then we create a new type. self._layer_type = BaseSensor.LayerTypeSequence( layer_type_sequence=self._sensor_instance.radiance_properties.layer_type_sequence, + default_parameters=LayerBySequenceParameters(), stable_ctr=True, ) elif ( @@ -3731,7 +3779,7 @@ class Sensor3DIrradiance(BaseSensor): sensor_instance : ansys.api.speos.scene.v2.scene_pb2.Scene.SensorInstance, optional Sensor instance to provide if the feature does not has to be created from scratch By default, ``None``, means that the feature is created from scratch by default. - default_values : bool + default_parameters : bool Uses default values when True. By default, ``True``. """ @@ -3743,7 +3791,7 @@ def __init__( description: str = "", metadata: Optional[Mapping[str, str]] = None, sensor_instance: Optional[ProtoScene.SensorInstance] = None, - default_values: bool = True, + default_parameters: Union[None, Irradiance3DSensorParameters] = None, ) -> None: if metadata is None: metadata = {} @@ -3762,11 +3810,45 @@ def __init__( # Attribute gathering more complex layer type self._layer_type = None - if default_values: - # Default values template - self.set_type_photometric().set_integration_planar() - # Default values properties - self.set_ray_file_type_none().set_layer_type_none() + if sensor_instance is None: + if default_parameters is None: + default_parameters = Irradiance3DSensorParameters() + + if isinstance(default_parameters.sensor_type, ColorimetricParameters): + self._type = Sensor3DIrradiance.Colorimetric( + sensor_type_colorimetric=self._sensor_template.irradiance_3d.type_colorimetric, + default_parameters=default_parameters.sensor_type, + stable_ctr=True, + ) + elif default_parameters == "radiometric": + self._type = Sensor3DIrradiance.Radiometric( + sensor_type_radiometric=self._sensor_template.irradiance_3d.type_radiometric, + default_parameters=default_parameters, + stable_ctr=True, + ) + elif default_parameters == "photometric": + self._type = Sensor3DIrradiance.Photometric( + sensor_type_photometric=self._sensor_template.irradiance_3d.type_radiometric, + default_parameters=default_parameters, + stable_ctr=True, + ) + if default_parameters.geometries: + self.geometries = default_parameters.geometries + if default_parameters.layer_type == "none": + self.set_layer_type_none() + elif default_parameters.layer_type == "by_source": + self.set_layer_type_source() + match default_parameters.rayfile_type: + case "none": + self.set_ray_file_type_none() + case "classic": + self.set_ray_file_type_classic() + case "polarization": + self.set_ray_file_type_polarization() + case "tm25": + self.set_ray_file_type_tm25() + case "tm25_no_polarization": + self.set_ray_file_type_tm25_no_polarization() class Radiometric: """Class computing the radiant intensity (in W.sr-1). @@ -3777,7 +3859,7 @@ class Radiometric: ---------- illuminance_type : ansys.api.speos.sensor.v1.sensor_pb2.TypeRadiometric SensorTypeColorimetric protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -3791,7 +3873,7 @@ class Radiometric: def __init__( self, sensor_type_radiometric: sensor_pb2.TypeRadiometric, - default_values: bool = True, + default_parameters: Union[None, Irradiance3DSensorParameters] = None, stable_ctr: bool = True, ) -> None: if not stable_ctr: @@ -3799,14 +3881,23 @@ def __init__( self._sensor_type_radiometric = sensor_type_radiometric - self._integration_type = Sensor3DIrradiance.Measures( - illuminance_type=self._sensor_type_radiometric.integration_type_planar, - default_values=default_values, - stable_ctr=stable_ctr, - ) - - if default_values: - self.set_integration_planar() + if default_parameters: + match default_parameters.integration_type: + case "planar": + self.set_integration_planar() + case "radial": + self.set_integration_radial() + self._integration_type = Sensor3DIrradiance.Measures( + illuminance_type=self._sensor_type_radiometric.integration_type_planar, + default_parameters=default_parameters.measures, + stable_ctr=stable_ctr, + ) + else: + self._integration_type = Sensor3DIrradiance.Measures( + illuminance_type=self._sensor_type_radiometric.integration_type_planar, + default_parameters=None, + stable_ctr=stable_ctr, + ) def set_integration_planar(self) -> Sensor3DIrradiance.Measures: """Set integration planar. @@ -3820,7 +3911,7 @@ def set_integration_planar(self) -> Sensor3DIrradiance.Measures: if not isinstance(self._integration_type, Sensor3DIrradiance.Measures): self._integration_type = Sensor3DIrradiance.Measures( illuminance_type=self._sensor_type_radiometric.integration_type_planar, - default_values=True, + default_parameters=True, stable_ctr=True, ) elif ( @@ -3847,7 +3938,7 @@ class Photometric: ---------- illuminance_type : ansys.api.speos.sensor.v1.sensor_pb2.TypePhotometric SensorTypeColorimetric protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -3861,22 +3952,31 @@ class Photometric: def __init__( self, sensor_type_photometric: sensor_pb2.TypePhotometric, - default_values: bool = True, + default_parameters: Union[None, Irradiance3DSensorParameters] = None, stable_ctr: bool = True, ) -> None: if not stable_ctr: - raise RuntimeError("Radiometric class instantiated outside of class scope") + raise RuntimeError("Photometric class instantiated outside of class scope") self._sensor_type_photometric = sensor_type_photometric - self._integration_type = Sensor3DIrradiance.Measures( - illuminance_type=self._sensor_type_photometric.integration_type_planar, - default_values=default_values, - stable_ctr=stable_ctr, - ) - - if default_values: - self.set_integration_planar() + if default_parameters: + match default_parameters.integration_type: + case "planar": + self.set_integration_planar() + case "radial": + self.set_integration_radial() + self._integration_type = Sensor3DIrradiance.Measures( + illuminance_type=self._sensor_type_photometric.integration_type_planar, + default_parameters=default_parameters.measures, + stable_ctr=stable_ctr, + ) + else: + self._integration_type = Sensor3DIrradiance.Measures( + illuminance_type=self._sensor_type_photometric.integration_type_planar, + default_parameters=None, + stable_ctr=stable_ctr, + ) def set_integration_planar(self) -> Sensor3DIrradiance.Measures: """Set integration planar. @@ -3890,7 +3990,7 @@ def set_integration_planar(self) -> Sensor3DIrradiance.Measures: if not isinstance(self._integration_type, Sensor3DIrradiance.Measures): self._integration_type = Sensor3DIrradiance.Measures( illuminance_type=self._sensor_type_photometric.integration_type_planar, - default_values=True, + default_parameters=True, stable_ctr=True, ) elif ( @@ -3919,7 +4019,7 @@ class Measures: ---------- illuminance_type : ansys.api.speos.sensor.v1.sensor_pb2.IntegrationTypePlanar SensorTypeColorimetric protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -3933,19 +4033,19 @@ class Measures: def __init__( self, illuminance_type: sensor_pb2.IntegrationTypePlanar, - default_values: bool = True, + default_parameters: Union[None, MeasuresParameters] = None, stable_ctr: bool = False, ): if not stable_ctr: - msg = "WavelengthsRange class instantiated outside of class scope" + msg = "Measures class instantiated outside of class scope" raise RuntimeError(msg) self._illuminance_type = illuminance_type - if default_values: + if default_parameters: # Default values - self.reflection = True - self.transmission = True - self.absorption = True + self.reflection = default_parameters.reflection + self.transmission = default_parameters.transmission + self.absorption = default_parameters.absorption @property def reflection(self) -> bool: @@ -4040,7 +4140,7 @@ class Colorimetric: ---------- illuminance_type : ansys.api.speos.sensor.v1.sensor_pb2.TypeColorimetric SensorTypeColorimetric protobuf object to modify. - default_values : bool + default_parameters : bool Uses default values when True. stable_ctr : bool Variable to indicate if usage is inside class scope @@ -4054,7 +4154,7 @@ class Colorimetric: def __init__( self, sensor_type_colorimetric: sensor_pb2.TypeColorimetric, - default_values: bool = True, + default_parameters: Union[None, ColorimetricParameters] = None, stable_ctr: bool = False, ) -> None: if not stable_ctr: @@ -4063,15 +4163,20 @@ def __init__( self._sensor_type_colorimetric = sensor_type_colorimetric # Attribute to keep track of wavelength range object - self._wavelengths_range = BaseSensor.WavelengthsRange( - wavelengths_range=self._sensor_type_colorimetric, - default_values=default_values, - stable_ctr=stable_ctr, - ) - if default_values: + if default_parameters: # Default values - self.set_wavelengths_range() + self._wavelengths_range = BaseSensor.WavelengthsRange( + wavelengths_range=self._sensor_type_colorimetric, + default_parameters=default_parameters.wavelength_range, + stable_ctr=stable_ctr, + ) + else: + self._wavelengths_range = BaseSensor.WavelengthsRange( + wavelengths_range=self._sensor_type_colorimetric, + default_parameters=default_parameters, + stable_ctr=stable_ctr, + ) def set_wavelengths_range(self) -> BaseSensor.WavelengthsRange: """Set the range of wavelengths. @@ -4164,13 +4269,14 @@ def set_type_photometric(self) -> Sensor3DIrradiance.Photometric: # Happens in case of project created via load of speos file self._type = Sensor3DIrradiance.Photometric( self._sensor_template.irradiance_3d.type_photometric, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, Sensor3DIrradiance.Photometric): # if the _type is not Colorimetric then we create a new type. self._type = Sensor3DIrradiance.Photometric( self._sensor_template.irradiance_3d.type_photometric, + default_parameters=None, stable_ctr=True, ) elif ( @@ -4197,13 +4303,14 @@ def set_type_radiometric(self) -> Sensor3DIrradiance.Radiometric: # Happens in case of project created via load of speos file self._type = Sensor3DIrradiance.Radiometric( sensor_type_radiometric=self._sensor_template.irradiance_3d.type_radiometric, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, Sensor3DIrradiance.Radiometric): # if the _type is not Colorimetric then we create a new type. self._type = Sensor3DIrradiance.Radiometric( sensor_type_radiometric=self._sensor_template.irradiance_3d.type_radiometric, + default_parameters=None, stable_ctr=True, ) elif ( @@ -4231,13 +4338,14 @@ def set_type_colorimetric(self) -> Sensor3DIrradiance.Colorimetric: # Happens in case of project created via load of speos file self._type = Sensor3DIrradiance.Colorimetric( sensor_type_colorimetric=self._sensor_template.irradiance_3d.type_colorimetric, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._type, BaseSensor.Colorimetric): # if the _type is not Colorimetric then we create a new type. self._type = Sensor3DIrradiance.Colorimetric( sensor_type_colorimetric=self._sensor_template.irradiance_3d.type_colorimetric, + default_parameters=None, stable_ctr=True, ) elif ( From 41a11f6fa04fe4a2d7f01ed81c7ba99d256a203f Mon Sep 17 00:00:00 2001 From: sthoene Date: Tue, 23 Sep 2025 13:46:19 +0200 Subject: [PATCH 38/47] unit test missing --- src/ansys/speos/core/generic/constants.py | 8 +++++--- src/ansys/speos/core/sensor.py | 7 ++++--- tests/local_config.json | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 901529f98..839b61e38 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -213,12 +213,14 @@ class PhotometricCameraParameters: """PNG bit resolution of the Camera Sensor.""" wavelength_range = WavelengthsRangeParameters() """Wavelength range of the Camera Sensor.""" - ACQUISITION_INTEGRATION: float = 0.01 + acquisition_integration_time: float = 0.01 """Integration Time value for the Camera Sensor.""" - ACQUISITION_LAG_TIME: float = 0 + acquisition_lag_time: float = 0 """Acquisition lag time for the Camera Sensor.""" - GAMMA_CORRECTION: float = 2.2 + gamma_correction: float = 2.2 """Gamma correction Value for the Camera Sensor.""" + transmittance_file_uri: str = "" + """Transmittance spectrum location""" @dataclass diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 08db461a5..980bb75f1 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -1630,9 +1630,10 @@ def __init__( if isinstance(default_parameters, PhotometricCameraParameters): # Default values - self.acquisition_integration = default_parameters.ACQUISITION_INTEGRATION - self.acquisition_lag_time = default_parameters.ACQUISITION_LAG_TIME - self.gamma_correction = default_parameters.GAMMA_CORRECTION + self.acquisition_integration = default_parameters.acquisition_integration_time + self.acquisition_lag_time = default_parameters.acquisition_lag_time + self.gamma_correction = default_parameters.gamma_correction + self.transmittance_file_uri = default_parameters.transmittance_file_uri match default_parameters.png_bits: case "png_08": self.set_png_bits_08() diff --git a/tests/local_config.json b/tests/local_config.json index 08dd6798f..302fe8f3a 100644 --- a/tests/local_config.json +++ b/tests/local_config.json @@ -1,5 +1,5 @@ { - "SpeosServerOnDocker": true, + "SpeosServerOnDocker": false, "SpeosContainerName" : "speos-rpc", - "SpeosServerPort": 50098 + "SpeosServerPort": 50052 } From b3fe0b7e7a478d2ef7e7794de01e817a10d485a2 Mon Sep 17 00:00:00 2001 From: sthoene Date: Fri, 26 Sep 2025 16:07:00 +0200 Subject: [PATCH 39/47] fix unit test except camera --- src/ansys/speos/core/generic/constants.py | 2 - src/ansys/speos/core/sensor.py | 81 +++--- tests/core/test_sensor.py | 323 ++++++++++++---------- 3 files changed, 222 insertions(+), 184 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 839b61e38..807698c43 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -382,5 +382,3 @@ class Irradiance3DSensorParameters: """Layer separation type.""" geometries: list = None """Sensor geometry.""" - - pass diff --git a/src/ansys/speos/core/sensor.py b/src/ansys/speos/core/sensor.py index 980bb75f1..5b6303f66 100644 --- a/src/ansys/speos/core/sensor.py +++ b/src/ansys/speos/core/sensor.py @@ -1328,9 +1328,12 @@ def __init__( if default_parameters: # Default values self._balance_mode_display.SetInParent() - self.red_display_file_uri = default_parameters.red_display_file_uri - self.green_display_file_uri = default_parameters.green_display_file_uri - self.blue_display_file_uri = default_parameters.blue_display_file_uri + if default_parameters.red_display_file_uri: + self.red_display_file_uri = default_parameters.red_display_file_uri + if default_parameters.green_display_file_uri: + self.green_display_file_uri = default_parameters.green_display_file_uri + if default_parameters.green_display_file_uri: + self.blue_display_file_uri = default_parameters.blue_display_file_uri @property def red_display_file_uri(self) -> str: @@ -1432,9 +1435,12 @@ def __init__( self.set_balance_mode_grey_world() elif default_parameters.balance_mode == "none": self.set_balance_mode_none() - self.red_spectrum_file_uri = default_parameters.red_spectrum_file_uri - self.green_spectrum_file_uri = default_parameters.green_spectrum_file_uri - self.blue_spectrum_file_uri = default_parameters.blue_spectrum_file_uri + if default_parameters.red_spectrum_file_uri: + self.red_spectrum_file_uri = default_parameters.red_spectrum_file_uri + if default_parameters.green_spectrum_file_uri: + self.green_spectrum_file_uri = default_parameters.green_spectrum_file_uri + if default_parameters.blue_spectrum_file_uri: + self.blue_spectrum_file_uri = default_parameters.blue_spectrum_file_uri @property def red_spectrum_file_uri(self) -> str: @@ -1628,12 +1634,13 @@ def __init__( # Attribute to keep track of wavelength range object - if isinstance(default_parameters, PhotometricCameraParameters): + if default_parameters: # Default values self.acquisition_integration = default_parameters.acquisition_integration_time self.acquisition_lag_time = default_parameters.acquisition_lag_time self.gamma_correction = default_parameters.gamma_correction - self.transmittance_file_uri = default_parameters.transmittance_file_uri + if default_parameters.transmittance_file_uri: + self.transmittance_file_uri = default_parameters.transmittance_file_uri match default_parameters.png_bits: case "png_08": self.set_png_bits_08() @@ -1667,8 +1674,6 @@ def __init__( default_parameters=None, stable_ctr=stable_ctr, ) - else: - raise TypeError("Default Photometric Parameters are incorrect") @property def acquisition_integration(self) -> float: @@ -1873,13 +1878,14 @@ def set_mode_color(self) -> SensorCamera.Photometric.Color: # Happens in case of project created via load of speos file self._mode = SensorCamera.Photometric.Color( mode_color=self._mode_photometric.color_mode_color, - default_values=False, + default_parameters=None, stable_ctr=True, ) elif not isinstance(self._mode, SensorCamera.Photometric.Color): # if the _mode is not Color then we create a new type. self._mode = SensorCamera.Photometric.Color( mode_color=self._mode_photometric.color_mode_color, + default_parameters=None, stable_ctr=True, ) elif self._mode._mode_color is not self._mode_photometric.color_mode_color: @@ -1958,16 +1964,6 @@ def __init__( if sensor_instance is None: if not default_parameters: default_parameters = CameraSensorParameters() - self.imager_distance = default_parameters.imager_distance - self.focal_length = default_parameters.focal_length - self.f_number = default_parameters.f_number - self.horz_pixel = default_parameters.horz_pixel - self.vert_pixel = default_parameters.vert_pixel - self.width = default_parameters.width - self.height = default_parameters.height - self.axis_system = default_parameters.axis_system - self.lxp_path_number = default_parameters.lxp_path_number - if isinstance(default_parameters.sensor_type_parameters, PhotometricCameraParameters): self._type = SensorCamera.Photometric( mode_photometric=self._sensor_template.camera_sensor_template.sensor_mode_photometric, @@ -1977,6 +1973,15 @@ def __init__( ) else: self.set_mode_geometric() + self.imager_distance = default_parameters.imager_distance + self.focal_length = default_parameters.focal_length + self.f_number = default_parameters.f_number + self.horz_pixel = default_parameters.horz_pixel + self.vert_pixel = default_parameters.vert_pixel + self.width = default_parameters.width + self.height = default_parameters.height + self.axis_system = default_parameters.axis_system + self.lxp_path_number = default_parameters.lxp_path_number @property def visual_data(self) -> _VisualData: @@ -2449,6 +2454,11 @@ def __init__( if default_parameters is None: default_parameters = IrradianceSensorParameters() # Default values template + self._sensor_dimensions = self.Dimensions( + sensor_dimensions=self._sensor_template.irradiance_sensor_template.dimensions, + default_parameters=default_parameters.dimensions, + stable_ctr=True, + ) if isinstance(default_parameters.sensor_type, ColorimetricParameters): self._type = BaseSensor.Colorimetric( @@ -2462,9 +2472,9 @@ def __init__( default_parameters=default_parameters.sensor_type, stable_ctr=True, ) - elif default_parameters == "radiometric": + elif default_parameters.sensor_type == "radiometric": self.set_type_radiometric() - elif default_parameters == "photometric": + elif default_parameters.sensor_type == "photometric": self.set_type_photometric() match default_parameters.integration_type: @@ -2720,6 +2730,7 @@ def set_type_colorimetric(self) -> BaseSensor.Colorimetric: # if the _type is not Colorimetric then we create a new type. self._type = BaseSensor.Colorimetric( sensor_type_colorimetric=self._sensor_template.irradiance_sensor_template.sensor_type_colorimetric, + default_parameters=ColorimetricParameters(), stable_ctr=True, ) elif ( @@ -3269,9 +3280,9 @@ def __init__( default_parameters=default_parameters.sensor_type, stable_ctr=True, ) - elif default_parameters == "radiometric": + elif default_parameters.sensor_type == "radiometric": self.set_type_radiometric() - elif default_parameters == "photometric": + elif default_parameters.sensor_type == "photometric": self.set_type_photometric() if default_parameters.layer_type == "none": @@ -3821,15 +3832,15 @@ def __init__( default_parameters=default_parameters.sensor_type, stable_ctr=True, ) - elif default_parameters == "radiometric": + elif default_parameters.sensor_type == "radiometric": self._type = Sensor3DIrradiance.Radiometric( sensor_type_radiometric=self._sensor_template.irradiance_3d.type_radiometric, default_parameters=default_parameters, stable_ctr=True, ) - elif default_parameters == "photometric": + elif default_parameters.sensor_type == "photometric": self._type = Sensor3DIrradiance.Photometric( - sensor_type_photometric=self._sensor_template.irradiance_3d.type_radiometric, + sensor_type_photometric=self._sensor_template.irradiance_3d.type_photometric, default_parameters=default_parameters, stable_ctr=True, ) @@ -3881,7 +3892,7 @@ def __init__( raise RuntimeError("Radiometric class instantiated outside of class scope") self._sensor_type_radiometric = sensor_type_radiometric - + self._integration_type = None if default_parameters: match default_parameters.integration_type: case "planar": @@ -3912,7 +3923,7 @@ def set_integration_planar(self) -> Sensor3DIrradiance.Measures: if not isinstance(self._integration_type, Sensor3DIrradiance.Measures): self._integration_type = Sensor3DIrradiance.Measures( illuminance_type=self._sensor_type_radiometric.integration_type_planar, - default_parameters=True, + default_parameters=MeasuresParameters(), stable_ctr=True, ) elif ( @@ -3960,7 +3971,7 @@ def __init__( raise RuntimeError("Photometric class instantiated outside of class scope") self._sensor_type_photometric = sensor_type_photometric - + self._integration_type = None if default_parameters: match default_parameters.integration_type: case "planar": @@ -3991,7 +4002,7 @@ def set_integration_planar(self) -> Sensor3DIrradiance.Measures: if not isinstance(self._integration_type, Sensor3DIrradiance.Measures): self._integration_type = Sensor3DIrradiance.Measures( illuminance_type=self._sensor_type_photometric.integration_type_planar, - default_parameters=True, + default_parameters=MeasuresParameters(), stable_ctr=True, ) elif ( @@ -4277,7 +4288,7 @@ def set_type_photometric(self) -> Sensor3DIrradiance.Photometric: # if the _type is not Colorimetric then we create a new type. self._type = Sensor3DIrradiance.Photometric( self._sensor_template.irradiance_3d.type_photometric, - default_parameters=None, + default_parameters=Irradiance3DSensorParameters(), stable_ctr=True, ) elif ( @@ -4311,7 +4322,7 @@ def set_type_radiometric(self) -> Sensor3DIrradiance.Radiometric: # if the _type is not Colorimetric then we create a new type. self._type = Sensor3DIrradiance.Radiometric( sensor_type_radiometric=self._sensor_template.irradiance_3d.type_radiometric, - default_parameters=None, + default_parameters=Irradiance3DSensorParameters(), stable_ctr=True, ) elif ( @@ -4346,7 +4357,7 @@ def set_type_colorimetric(self) -> Sensor3DIrradiance.Colorimetric: # if the _type is not Colorimetric then we create a new type. self._type = Sensor3DIrradiance.Colorimetric( sensor_type_colorimetric=self._sensor_template.irradiance_3d.type_colorimetric, - default_parameters=None, + default_parameters=ColorimetricParameters(), stable_ctr=True, ) elif ( diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index ab98d9d74..877f5281a 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -27,7 +27,17 @@ from ansys.api.speos.sensor.v1 import camera_sensor_pb2 from ansys.speos.core import Body, GeoRef, Project, Speos, sensor -from ansys.speos.core.generic.constants import ORIGIN, SENSOR +from ansys.speos.core.generic.constants import ( + ORIGIN, + BalanceModeUserWhiteParameters, + CameraSensorParameters, + ColorimetricParameters, + IrradianceSensorParameters, + LayerBySequenceParameters, + RadianceSensorParameters, + SpectralParameters, + WavelengthsRangeParameters, +) from ansys.speos.core.sensor import ( Sensor3DIrradiance, SensorCamera, @@ -42,6 +52,7 @@ def test_create_camera_sensor(speos: Speos): """Test creation of camera sensor.""" p = Project(speos=speos) + sensor_parameters = CameraSensorParameters() # Default value sensor1 = p.create_sensor(name="Camera.1", feature_type=SensorCamera) assert isinstance(sensor1, SensorCamera) @@ -54,33 +65,55 @@ def test_create_camera_sensor(speos: Speos): sensor1.set_mode_photometric().set_mode_color().blue_spectrum_file_uri = str( Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" ) + sensor1.distortion_file_uri = str( + Path(test_path) / "CameraInputFiles" / "CameraDistortion_130deg.OPTDistortion" + ) + sensor1.commit() assert sensor1.sensor_template_link is not None assert sensor1.sensor_template_link.get().HasField("camera_sensor_template") camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template - assert camera_sensor_template.focal_length == SENSOR.CAMERASENSOR.focal_length - assert camera_sensor_template.imager_distance == SENSOR.CAMERASENSOR.imager_distance + assert camera_sensor_template.focal_length == sensor_parameters.focal_length + assert camera_sensor_template.imager_distance == sensor_parameters.imager_distance assert camera_sensor_template.distortion_file_uri == "" - assert camera_sensor_template.f_number == SENSOR.CAMERASENSOR.f_number - assert camera_sensor_template.horz_pixel == SENSOR.CAMERASENSOR.horz_pixel - assert camera_sensor_template.vert_pixel == SENSOR.CAMERASENSOR.vert_pixel - assert camera_sensor_template.width == SENSOR.CAMERASENSOR.width - assert camera_sensor_template.height == SENSOR.CAMERASENSOR.height + assert camera_sensor_template.f_number == sensor_parameters.f_number + assert camera_sensor_template.horz_pixel == sensor_parameters.horz_pixel + assert camera_sensor_template.vert_pixel == sensor_parameters.vert_pixel + assert camera_sensor_template.width == sensor_parameters.width + assert camera_sensor_template.height == sensor_parameters.height assert camera_sensor_template.HasField("sensor_mode_photometric") mode_photometric = camera_sensor_template.sensor_mode_photometric - assert mode_photometric.acquisition_integration == SENSOR.CAMERASENSOR.ACQUISITION_INTEGRATION - assert mode_photometric.acquisition_lag_time == SENSOR.CAMERASENSOR.ACQUISITION_LAG_TIME - assert mode_photometric.transmittance_file_uri == "" + assert ( + mode_photometric.acquisition_integration + == sensor_parameters.sensor_type_parameters.acquisition_integration_time + ) + assert ( + mode_photometric.acquisition_lag_time + == sensor_parameters.sensor_type_parameters.acquisition_lag_time + ) + assert ( + mode_photometric.transmittance_file_uri + == sensor_parameters.sensor_type_parameters.transmittance_file_uri + ) assert math.isclose( a=mode_photometric.gamma_correction, - b=SENSOR.CAMERASENSOR.GAMMA_CORRECTION, + b=sensor_parameters.sensor_type_parameters.gamma_correction, rel_tol=1.192092896e-07, ) assert mode_photometric.png_bits == camera_sensor_pb2.EnumSensorCameraPNGBits.PNG_16 assert mode_photometric.HasField("wavelengths_range") - assert mode_photometric.wavelengths_range.w_start == SENSOR.WAVELENGTHSRANGE.START - assert mode_photometric.wavelengths_range.w_end == SENSOR.WAVELENGTHSRANGE.END - assert mode_photometric.wavelengths_range.w_sampling == SENSOR.WAVELENGTHSRANGE.SAMPLING + assert ( + mode_photometric.wavelengths_range.w_start + == sensor_parameters.sensor_type_parameters.wavelength_range.start + ) + assert ( + mode_photometric.wavelengths_range.w_end + == sensor_parameters.sensor_type_parameters.wavelength_range.end + ) + assert ( + mode_photometric.wavelengths_range.w_sampling + == sensor_parameters.sensor_type_parameters.wavelength_range.sampling + ) assert mode_photometric.HasField("color_mode_color") assert mode_photometric.color_mode_color.red_spectrum_file_uri.endswith( "CameraSensitivityRed.spectrum" @@ -92,9 +125,14 @@ def test_create_camera_sensor(speos: Speos): "CameraSensitivityBlue.spectrum" ) assert mode_photometric.color_mode_color.HasField("balance_mode_none") - assert sensor1._sensor_instance.camera_properties.axis_system == ORIGIN - assert sensor1._sensor_instance.camera_properties.trajectory_file_uri == "" - assert sensor1.set_mode_photometric().trajectory_file_uri == "" + assert sensor1._sensor_instance.camera_properties.axis_system == sensor_parameters.axis_system + assert ( + sensor1._sensor_instance.camera_properties.trajectory_file_uri + == sensor_parameters.trajectory_fil_uri + ) + assert ( + sensor1.set_mode_photometric().trajectory_file_uri == sensor_parameters.trajectory_fil_uri + ) assert sensor1._sensor_instance.camera_properties.HasField("layer_type_none") # focal_length @@ -294,15 +332,15 @@ def test_create_camera_sensor(speos: Speos): assert mode_photometric.color_mode_color.HasField("balance_mode_userwhite") assert ( mode_photometric.color_mode_color.balance_mode_userwhite.red_gain - == SENSOR.CAMERASENSOR.GAIN + == sensor_parameters.sensor_type_parameters.color_mode.balance_mode.red_gain ) assert ( mode_photometric.color_mode_color.balance_mode_userwhite.green_gain - == SENSOR.CAMERASENSOR.GAIN + == sensor_parameters.sensor_type_parameters.color_mode.balance_mode.green_gain ) assert ( mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain - == SENSOR.CAMERASENSOR.GAIN + == sensor_parameters.sensor_type_parameters.color_mode.balance_mode.blue_gain ) balance_mode_user_white = ( @@ -491,7 +529,7 @@ def test_create_irradiance_sensor(speos: Speos): [0, 1, 2] ).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1]) root_part.commit() - + sensor_parameter = IrradianceSensorParameters() # Default value sensor1 = p.create_sensor(name="Irradiance.1", feature_type=SensorIrradiance) sensor1.commit() @@ -501,19 +539,19 @@ def test_create_irradiance_sensor(speos: Speos): assert sensor_template.HasField("sensor_type_photometric") assert sensor_template.HasField("illuminance_type_planar") assert sensor_template.HasField("dimensions") - assert sensor_template.dimensions.x_start == SENSOR.DIMENSIONS.X_START - assert sensor_template.dimensions.x_end == SENSOR.DIMENSIONS.X_END - assert sensor_template.dimensions.x_sampling == SENSOR.DIMENSIONS.X_SAMPLING - assert sensor_template.dimensions.y_start == SENSOR.DIMENSIONS.Y_START - assert sensor_template.dimensions.y_end == SENSOR.DIMENSIONS.Y_END - assert sensor_template.dimensions.y_sampling == SENSOR.DIMENSIONS.Y_SAMPLING + assert sensor_template.dimensions.x_start == sensor_parameter.dimensions.x_start + assert sensor_template.dimensions.x_end == sensor_parameter.dimensions.x_end + assert sensor_template.dimensions.x_sampling == sensor_parameter.dimensions.x_sampling + assert sensor_template.dimensions.y_start == sensor_parameter.dimensions.y_start + assert sensor_template.dimensions.y_end == sensor_parameter.dimensions.y_end + assert sensor_template.dimensions.y_sampling == sensor_parameter.dimensions.y_sampling assert sensor1._sensor_instance.HasField("irradiance_properties") irra_properties = sensor1._sensor_instance.irradiance_properties - assert irra_properties.axis_system == ORIGIN + assert irra_properties.axis_system == sensor_parameter.axis_system assert irra_properties.HasField("layer_type_none") assert irra_properties.ray_file_type == sensor1._sensor_instance.EnumRayFileType.RayFileNone assert irra_properties.integration_direction == [] - + color_parameters = ColorimetricParameters() # sensor_type_colorimetric # default wavelengths range sensor1.set_type_colorimetric() @@ -523,15 +561,15 @@ def test_create_irradiance_sensor(speos: Speos): assert sensor_template.sensor_type_colorimetric.HasField("wavelengths_range") assert ( sensor_template.sensor_type_colorimetric.wavelengths_range.w_start - == SENSOR.WAVELENGTHSRANGE.START + == color_parameters.wavelength_range.start ) assert ( sensor_template.sensor_type_colorimetric.wavelengths_range.w_end - == SENSOR.WAVELENGTHSRANGE.END + == color_parameters.wavelength_range.end ) assert ( sensor_template.sensor_type_colorimetric.wavelengths_range.w_sampling - == SENSOR.WAVELENGTHSRANGE.SAMPLING + == color_parameters.wavelength_range.sampling ) # chosen wavelengths range wavelengths_range = sensor1.set_type_colorimetric().set_wavelengths_range() @@ -552,6 +590,7 @@ def test_create_irradiance_sensor(speos: Speos): sensor_template = sensor1.sensor_template_link.get().irradiance_sensor_template assert sensor_template.HasField("sensor_type_radiometric") + spectral_parameters = SpectralParameters() # sensor_type_spectral # default wavelengths range sensor1.set_type_spectral() @@ -561,14 +600,15 @@ def test_create_irradiance_sensor(speos: Speos): assert sensor_template.sensor_type_spectral.HasField("wavelengths_range") assert ( sensor_template.sensor_type_spectral.wavelengths_range.w_start - == SENSOR.WAVELENGTHSRANGE.START + == spectral_parameters.wavelength_range.start ) assert ( - sensor_template.sensor_type_spectral.wavelengths_range.w_end == SENSOR.WAVELENGTHSRANGE.END + sensor_template.sensor_type_spectral.wavelengths_range.w_end + == spectral_parameters.wavelength_range.end ) assert ( sensor_template.sensor_type_spectral.wavelengths_range.w_sampling - == SENSOR.WAVELENGTHSRANGE.SAMPLING + == spectral_parameters.wavelength_range.sampling ) # chosen wavelengths range wavelengths_range = sensor1.set_type_spectral().set_wavelengths_range() @@ -803,125 +843,110 @@ def test_create_radiance_sensor(speos: Speos): [0, 1, 2] ).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1]) root_part.commit() - + sensor_parameter = RadianceSensorParameters() # Default value sensor1 = p.create_sensor(name="Radiance.1", feature_type=SensorRadiance) sensor1.commit() assert sensor1.sensor_template_link is not None assert sensor1.sensor_template_link.get().HasField("radiance_sensor_template") assert sensor1.sensor_template_link.get().name == "Radiance.1" - assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField( - "sensor_type_photometric" - ) - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.focal - == SENSOR.RADIANCESENSOR.focal_length - ) - assert sensor1.focal == SENSOR.RADIANCESENSOR.focal_length - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.integration_angle - == SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE - ) - assert sensor1.integration_angle == SENSOR.RADIANCESENSOR.INTEGRATION_ANGLE - assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField("dimensions") - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_start - == SENSOR.DIMENSIONS.X_START - ) - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_end - == SENSOR.DIMENSIONS.X_END - ) - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_sampling - == SENSOR.DIMENSIONS.X_SAMPLING - ) - assert sensor1.set_dimensions().x_sampling == SENSOR.DIMENSIONS.X_SAMPLING - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_start - == SENSOR.DIMENSIONS.Y_START - ) - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_end - == SENSOR.DIMENSIONS.Y_END - ) - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_sampling - == SENSOR.DIMENSIONS.Y_SAMPLING - ) - assert sensor1.set_dimensions().y_sampling == SENSOR.DIMENSIONS.Y_SAMPLING + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.HasField("sensor_type_photometric") + assert template.focal == sensor_parameter.focal_length + assert sensor1.focal == sensor_parameter.focal_length + assert template.integration_angle == sensor_parameter.integration_angle + assert sensor1.integration_angle == sensor_parameter.integration_angle + assert template.HasField("dimensions") + assert template.dimensions.x_start == sensor_parameter.dimensions.x_start + assert template.dimensions.x_end == sensor_parameter.dimensions.x_end + assert template.dimensions.x_sampling == sensor_parameter.dimensions.x_sampling + assert sensor1.set_dimensions().x_sampling == sensor_parameter.dimensions.x_sampling + assert template.dimensions.y_start == sensor_parameter.dimensions.y_start + assert template.dimensions.y_end == sensor_parameter.dimensions.y_end + assert template.dimensions.y_sampling == sensor_parameter.dimensions.y_sampling + assert sensor1.set_dimensions().y_sampling == sensor_parameter.dimensions.y_sampling assert sensor1._sensor_instance.HasField("radiance_properties") radiance_properties = sensor1._sensor_instance.radiance_properties - assert radiance_properties.axis_system == ORIGIN + assert radiance_properties.axis_system == sensor_parameter.axis_system assert radiance_properties.HasField("layer_type_none") assert radiance_properties.observer_point == [] # sensor_type_radiometric sensor1.set_type_radiometric() sensor1.commit() - assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField( - "sensor_type_radiometric" - ) + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.HasField("sensor_type_radiometric") - # sensor_type_spectral + # sensor_type_colorimetric + color_parameters = SpectralParameters() # default wavelengths range - sensor1.set_type_spectral() + sensor1.set_type_colorimetric() sensor1.commit() - assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField( - "sensor_type_spectral" + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.HasField("sensor_type_colorimetric") + assert template.sensor_type_colorimetric.HasField("wavelengths_range") + assert ( + template.sensor_type_colorimetric.wavelengths_range.w_start + == color_parameters.wavelength_range.start ) assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.HasField( - "wavelengths_range" - ) + template.sensor_type_colorimetric.wavelengths_range.w_end + == color_parameters.wavelength_range.end ) assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start - == SENSOR.WAVELENGTHSRANGE.START + template.sensor_type_colorimetric.wavelengths_range.w_sampling + == color_parameters.wavelength_range.sampling ) + + # sensor_type_spectral + spectral_parameters = SpectralParameters() + # default wavelengths range + sensor1.set_type_spectral() + sensor1.commit() + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.HasField("sensor_type_spectral") + assert template.sensor_type_spectral.HasField("wavelengths_range") assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_end - == SENSOR.WAVELENGTHSRANGE.END + template.sensor_type_spectral.wavelengths_range.w_start + == spectral_parameters.wavelength_range.start ) assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_sampling - == SENSOR.WAVELENGTHSRANGE.SAMPLING + template.sensor_type_spectral.wavelengths_range.w_end + == spectral_parameters.wavelength_range.end ) + assert ( + template.sensor_type_spectral.wavelengths_range.w_sampling + == spectral_parameters.wavelength_range.sampling + ) + # chosen wavelengths range wavelengths_range = sensor1.set_type_spectral().set_wavelengths_range() wavelengths_range.start = 450 wavelengths_range.end = 800 wavelengths_range.sampling = 15 sensor1.commit() - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start - == 450 - ) - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_end - == 800 - ) - assert ( - sensor1.sensor_template_link.get().radiance_sensor_template.sensor_type_spectral.wavelengths_range.w_sampling - == 15 - ) + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.sensor_type_spectral.wavelengths_range.w_start == 450 + assert template.sensor_type_spectral.wavelengths_range.w_end == 800 + assert template.sensor_type_spectral.wavelengths_range.w_sampling == 15 # sensor_type_photometric sensor1.set_type_photometric() sensor1.commit() - assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField( - "sensor_type_photometric" - ) + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.HasField("sensor_type_photometric") # focal sensor1.focal = 150.5 sensor1.commit() - assert sensor1.sensor_template_link.get().radiance_sensor_template.focal == 150.5 + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.focal == 150.5 # integration_angle sensor1.integration_angle = 4.5 sensor1.commit() - assert sensor1.sensor_template_link.get().radiance_sensor_template.integration_angle == 4.5 + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.integration_angle == 4.5 # dimensions sensor1.dimensions.x_start = -10 @@ -931,13 +956,14 @@ def test_create_radiance_sensor(speos: Speos): sensor1.dimensions.y_end = 20 sensor1.dimensions.y_sampling = 120 sensor1.commit() - assert sensor1.sensor_template_link.get().radiance_sensor_template.HasField("dimensions") - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_start == -10.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_end == 10.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.x_sampling == 60 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_start == -20.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_end == 20.0 - assert sensor1.sensor_template_link.get().radiance_sensor_template.dimensions.y_sampling == 120 + template = sensor1.sensor_template_link.get().radiance_sensor_template + assert template.HasField("dimensions") + assert template.dimensions.x_start == -10.0 + assert template.dimensions.x_end == 10.0 + assert template.dimensions.x_sampling == 60 + assert template.dimensions.y_start == -20.0 + assert template.dimensions.y_end == 20.0 + assert template.dimensions.y_sampling == 120 # properties # axis_system @@ -1069,7 +1095,6 @@ def test_create_3d_irradiance_sensor(speos: Speos): # planar integration # layer type none # measure reflection, transmission, absorption - backend_photometric_info = sensor_3d.sensor_template_link.get() assert sensor_3d.sensor_template_link is not None assert backend_photometric_info.name == "3d" @@ -1141,14 +1166,15 @@ def test_create_3d_irradiance_sensor(speos: Speos): # when change type into colorimetric, default properties: # colorimetric + color_parameters = ColorimetricParameters() # wavelength start 400 with end 700 # layer type none sensor_3d.set_type_colorimetric() sensor_3d.commit() assert sensor_3d.sensor_template_link.get().irradiance_3d.HasField("type_colorimetric") colorimetric_info = sensor_3d.sensor_template_link.get().irradiance_3d.type_colorimetric - assert colorimetric_info.wavelength_start == SENSOR.WAVELENGTHSRANGE.START - assert colorimetric_info.wavelength_end == SENSOR.WAVELENGTHSRANGE.END + assert colorimetric_info.wavelength_start == color_parameters.wavelength_range.start + assert colorimetric_info.wavelength_end == color_parameters.wavelength_range.end wavelengths_range = sensor_3d.set_type_colorimetric().set_wavelengths_range() wavelengths_range.start = 500 sensor_3d.commit() @@ -1222,14 +1248,15 @@ def test_reset_sensor(speos: Speos): # Create + commit sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorIrradiance) + sensor_parameter = IrradianceSensorParameters() sensor1.commit() assert ( sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start - == SENSOR.DIMENSIONS.X_START + == sensor_parameter.dimensions.x_start ) # local assert ( sensor1.sensor_template_link.get().irradiance_sensor_template.dimensions.x_start - == SENSOR.DIMENSIONS.X_START + == sensor_parameter.dimensions.x_start ) # server assert sensor1._sensor_instance.irradiance_properties.axis_system == ORIGIN # local assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == ORIGIN # server @@ -1260,11 +1287,11 @@ def test_reset_sensor(speos: Speos): sensor1.reset() assert ( sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start - == SENSOR.DIMENSIONS.X_START + == sensor_parameter.dimensions.x_start ) # local assert ( sensor1.sensor_template_link.get().irradiance_sensor_template.dimensions.x_start - == SENSOR.DIMENSIONS.X_START + == sensor_parameter.dimensions.x_start ) # server assert sensor1._sensor_instance.irradiance_properties.axis_system == ORIGIN # local assert p.scene_link.get().sensors[0].irradiance_properties.axis_system == ORIGIN # server @@ -1275,7 +1302,8 @@ def test_reset_sensor(speos: Speos): def test_irradiance_modify_after_reset(speos: Speos): """Test reset of irradiance sensor, and then modify.""" p = Project(speos=speos) - + wl = WavelengthsRangeParameters() + sensor_parameter = IrradianceSensorParameters() # Create + commit sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorIrradiance) sensor1.set_type_spectral() @@ -1294,7 +1322,7 @@ def test_irradiance_modify_after_reset(speos: Speos): # Intermediate class for type : spectral assert ( sensor1._sensor_template.irradiance_sensor_template.sensor_type_spectral.wavelengths_range.w_start - == SENSOR.WAVELENGTHSRANGE.START + == wl.start ) sensor1.set_type_spectral().set_wavelengths_range().start = 500 assert ( @@ -1304,7 +1332,7 @@ def test_irradiance_modify_after_reset(speos: Speos): # Intermediate class for dimensions assert ( sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start - == SENSOR.DIMENSIONS.X_START + == sensor_parameter.dimensions.x_start ) sensor1.set_dimensions().x_start = -100 assert sensor1._sensor_template.irradiance_sensor_template.dimensions.x_start == -100 @@ -1327,9 +1355,10 @@ def test_irradiance_modify_after_reset(speos: Speos): 1, ] # Intermediate class for layer type + layer_parameters = LayerBySequenceParameters() assert ( sensor1._sensor_instance.irradiance_properties.layer_type_sequence.maximum_nb_of_sequence - == SENSOR.LAYERTYPES.MAXIMUM_NB_OF_SEQUENCE + == layer_parameters.maximum_nb_of_sequence ) sensor1.set_layer_type_sequence().maximum_nb_of_sequence = 15 assert ( @@ -1343,7 +1372,8 @@ def test_irradiance_modify_after_reset(speos: Speos): def test_radiance_modify_after_reset(speos: Speos): """Test reset of radiance sensor, and then modify.""" p = Project(speos=speos) - + sensor_parameter = RadianceSensorParameters() + wl = WavelengthsRangeParameters() # Create + commit sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorRadiance) assert isinstance(sensor1, SensorRadiance) @@ -1356,16 +1386,13 @@ def test_radiance_modify_after_reset(speos: Speos): # Modify after a reset # Template - assert ( - sensor1._sensor_template.radiance_sensor_template.focal - == SENSOR.RADIANCESENSOR.focal_length - ) + assert sensor1._sensor_template.radiance_sensor_template.focal == sensor_parameter.focal_length sensor1.focal = 100 assert sensor1._sensor_template.radiance_sensor_template.focal == 100 # Intermediate class for type : colorimetric assert ( sensor1._sensor_template.radiance_sensor_template.sensor_type_colorimetric.wavelengths_range.w_start - == SENSOR.WAVELENGTHSRANGE.START + == wl.start ) sensor1.set_type_colorimetric().set_wavelengths_range().start = 500 assert ( @@ -1374,7 +1401,7 @@ def test_radiance_modify_after_reset(speos: Speos): ) assert ( sensor1._sensor_template.radiance_sensor_template.sensor_type_colorimetric.wavelengths_range.w_end - == SENSOR.WAVELENGTHSRANGE.END + == wl.end ) sensor1.set_type_colorimetric().set_wavelengths_range().start = 500 assert ( @@ -1384,7 +1411,7 @@ def test_radiance_modify_after_reset(speos: Speos): # Intermediate class for dimensions assert ( sensor1._sensor_template.radiance_sensor_template.dimensions.x_start - == SENSOR.DIMENSIONS.X_START + == sensor_parameter.dimensions.x_start ) sensor1.set_dimensions().x_start = -100 assert sensor1._sensor_template.radiance_sensor_template.dimensions.x_start == -100 @@ -1392,7 +1419,7 @@ def test_radiance_modify_after_reset(speos: Speos): assert ( sensor1._sensor_template.radiance_sensor_template.dimensions.x_end - == SENSOR.DIMENSIONS.X_END + == sensor_parameter.dimensions.x_end ) sensor1.set_dimensions().x_end = 100 assert sensor1._sensor_template.radiance_sensor_template.dimensions.x_end == 100 @@ -1400,7 +1427,7 @@ def test_radiance_modify_after_reset(speos: Speos): assert ( sensor1._sensor_template.radiance_sensor_template.dimensions.y_start - == SENSOR.DIMENSIONS.Y_START + == sensor_parameter.dimensions.y_start ) sensor1.set_dimensions().y_start = -100 assert sensor1._sensor_template.radiance_sensor_template.dimensions.y_start == -100 @@ -1408,7 +1435,7 @@ def test_radiance_modify_after_reset(speos: Speos): assert ( sensor1._sensor_template.radiance_sensor_template.dimensions.y_end - == SENSOR.DIMENSIONS.Y_END + == sensor_parameter.dimensions.y_end ) sensor1.set_dimensions().y_end = 100 assert sensor1._sensor_template.radiance_sensor_template.dimensions.y_end == 100 @@ -1432,9 +1459,10 @@ def test_radiance_modify_after_reset(speos: Speos): 1, ] # Intermediate class for layer type + layer_parameters = LayerBySequenceParameters() assert ( sensor1._sensor_instance.radiance_properties.layer_type_sequence.maximum_nb_of_sequence - == SENSOR.LAYERTYPES.MAXIMUM_NB_OF_SEQUENCE + == layer_parameters.maximum_nb_of_sequence ) sensor1.set_layer_type_sequence().maximum_nb_of_sequence = 15 assert ( @@ -1448,7 +1476,7 @@ def test_radiance_modify_after_reset(speos: Speos): def test_camera_modify_after_reset(speos: Speos): """Test reset of camera sensor, and then modify.""" p = Project(speos=speos) - + sensor_parameter = CameraSensorParameters() # Create + commit sensor1 = p.create_sensor(name="Sensor.1", feature_type=SensorCamera) assert isinstance(sensor1, SensorCamera) @@ -1473,14 +1501,14 @@ def test_camera_modify_after_reset(speos: Speos): # Template assert ( sensor1._sensor_template.camera_sensor_template.focal_length - == SENSOR.CAMERASENSOR.focal_length + == sensor_parameter.focal_length ) sensor1.focal_length = 40 assert sensor1._sensor_template.camera_sensor_template.focal_length == 40 # Intermediate class for mode : photometric + wavelengths assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_start - == SENSOR.WAVELENGTHSRANGE.START + == sensor_parameter.sensor_type_parameters.wavelength_range.start ) sensor1.set_mode_photometric().set_wavelengths_range().start = 500 assert ( @@ -1489,7 +1517,7 @@ def test_camera_modify_after_reset(speos: Speos): ) assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.wavelengths_range.w_end - == SENSOR.WAVELENGTHSRANGE.END + == sensor_parameter.sensor_type_parameters.wavelength_range.end ) sensor1.set_mode_photometric().set_wavelengths_range().end = 800 assert ( @@ -1497,9 +1525,10 @@ def test_camera_modify_after_reset(speos: Speos): == 800 ) # Intermediate class for color mode + balance mode + user_white = BalanceModeUserWhiteParameters() assert ( sensor1._sensor_template.camera_sensor_template.sensor_mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain - == SENSOR.CAMERASENSOR.GAIN + == user_white.blue_gain ) color = sensor1.set_mode_photometric().set_mode_color() white_mode = color.set_balance_mode_user_white() @@ -1510,7 +1539,7 @@ def test_camera_modify_after_reset(speos: Speos): ) # Props - assert sensor1._sensor_instance.camera_properties.axis_system == ORIGIN + assert sensor1._sensor_instance.camera_properties.axis_system == sensor_parameter.axis_system sensor1.axis_system = [50, 20, 10, 1, 0, 0, 0, 1, 0, 0, 0, 1] assert sensor1._sensor_instance.camera_properties.axis_system == [ 50, From d4171d44a68cfe49419cdb91cc062c54df27c781 Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 29 Sep 2025 11:24:56 +0200 Subject: [PATCH 40/47] fix unit test except camera --- tests/core/test_sensor.py | 10 ++++------ tests/local_config.json | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/core/test_sensor.py b/tests/core/test_sensor.py index 877f5281a..8acc6dad9 100644 --- a/tests/core/test_sensor.py +++ b/tests/core/test_sensor.py @@ -65,9 +65,6 @@ def test_create_camera_sensor(speos: Speos): sensor1.set_mode_photometric().set_mode_color().blue_spectrum_file_uri = str( Path(test_path) / "CameraInputFiles" / "CameraSensitivityBlue.spectrum" ) - sensor1.distortion_file_uri = str( - Path(test_path) / "CameraInputFiles" / "CameraDistortion_130deg.OPTDistortion" - ) sensor1.commit() assert sensor1.sensor_template_link is not None @@ -330,17 +327,18 @@ def test_create_camera_sensor(speos: Speos): camera_sensor_template = sensor1.sensor_template_link.get().camera_sensor_template mode_photometric = camera_sensor_template.sensor_mode_photometric assert mode_photometric.color_mode_color.HasField("balance_mode_userwhite") + default_userwhites = BalanceModeUserWhiteParameters() assert ( mode_photometric.color_mode_color.balance_mode_userwhite.red_gain - == sensor_parameters.sensor_type_parameters.color_mode.balance_mode.red_gain + == default_userwhites.red_gain ) assert ( mode_photometric.color_mode_color.balance_mode_userwhite.green_gain - == sensor_parameters.sensor_type_parameters.color_mode.balance_mode.green_gain + == default_userwhites.green_gain ) assert ( mode_photometric.color_mode_color.balance_mode_userwhite.blue_gain - == sensor_parameters.sensor_type_parameters.color_mode.balance_mode.blue_gain + == default_userwhites.blue_gain ) balance_mode_user_white = ( diff --git a/tests/local_config.json b/tests/local_config.json index 302fe8f3a..08dd6798f 100644 --- a/tests/local_config.json +++ b/tests/local_config.json @@ -1,5 +1,5 @@ { - "SpeosServerOnDocker": false, + "SpeosServerOnDocker": true, "SpeosContainerName" : "speos-rpc", - "SpeosServerPort": 50052 + "SpeosServerPort": 50098 } From e4487730586812f116adc5a624f0c8d458f634dc Mon Sep 17 00:00:00 2001 From: sthoene Date: Mon, 29 Sep 2025 14:13:22 +0200 Subject: [PATCH 41/47] fix default values --- src/ansys/speos/core/generic/constants.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 807698c43..0a6e98b98 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -205,13 +205,15 @@ class MonoChromaticParameters: class PhotometricCameraParameters: """Photometric Parameters for Camera.""" - color_mode: Union[MonoChromaticParameters, ColorParameters] = ColorParameters() + color_mode: Union[MonoChromaticParameters, ColorParameters] = field( + default_factory=ColorParameters + ) """Color mode of the Camera Sensor.""" layer_type: Union[LayerTypes.none, LayerTypes.by_source] = LayerTypes.none """Layer separation parameter.""" - png_bits: Union[PngBits.png_08, PngBits.png_10, PngBits.png_12, PngBits.png_16] = PngBits.png_16 + png_bits: PngBits = PngBits.png_16 """PNG bit resolution of the Camera Sensor.""" - wavelength_range = WavelengthsRangeParameters() + wavelength_range = field(default_factory=WavelengthsRangeParameters) """Wavelength range of the Camera Sensor.""" acquisition_integration_time: float = 0.01 """Integration Time value for the Camera Sensor.""" @@ -227,7 +229,9 @@ class PhotometricCameraParameters: class CameraSensorParameters: """Camera Sensor Parameters.""" - sensor_type_parameters: Union[None, PhotometricCameraParameters] = PhotometricCameraParameters() + sensor_type_parameters: Union[None, PhotometricCameraParameters] = field( + default_factory=PhotometricCameraParameters + ) """Camera sensor type None means geometric sensor""" axis_system: list[float] = field(default_factory=lambda: ORIGIN) """Location of the sensor Origin""" @@ -254,7 +258,7 @@ class CameraSensorParameters: class ColorimetricParameters: """Colorimetric settings of the Sensor.""" - wavelength_range = WavelengthsRangeParameters() + wavelength_range = field(default_factory=WavelengthsRangeParameters) """Wavelength range of the Sensor.""" @@ -262,7 +266,7 @@ class ColorimetricParameters: class SpectralParameters: """Colorimetric settings of the Sensor.""" - wavelength_range = WavelengthsRangeParameters() + wavelength_range = field(default_factory=WavelengthsRangeParameters) """Wavelength range of the Sensor.""" @@ -309,7 +313,7 @@ class MeasuresParameters: class IrradianceSensorParameters: """Irradiance Sensor Parameters.""" - dimensions: DimensionsParameters = DimensionsParameters() + dimensions: DimensionsParameters = field(default_factory=DimensionsParameters) """Dimensions of the sensor.""" axis_system: list[float] = field(default_factory=lambda: ORIGIN) """Position of the sensor.""" @@ -338,7 +342,7 @@ class IrradianceSensorParameters: class RadianceSensorParameters: """Radiance Sensor Constants.""" - dimensions: DimensionsParameters = DimensionsParameters() + dimensions: DimensionsParameters = field(default_factory=DimensionsParameters) """Dimensions of the sensor.""" axis_system: list[float] = field(default_factory=lambda: ORIGIN) """Position of the sensor.""" @@ -370,7 +374,7 @@ class Irradiance3DSensorParameters: SensorTypes.photometric ) """Type of the sensor.""" - measures = MeasuresParameters() + measures = field(default_factory=MeasuresParameters) """Measurement activation state.""" integration_type: Union[IntegrationTypes.planar, IntegrationTypes.radial] = ( IntegrationTypes.planar From 8909a867af7cef6674ae8d8dd19fb3b9665706e6 Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 2 Oct 2025 13:40:31 +0200 Subject: [PATCH 42/47] fix default values --- src/ansys/speos/core/generic/constants.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 0a6e98b98..d4344d959 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -213,7 +213,7 @@ class PhotometricCameraParameters: """Layer separation parameter.""" png_bits: PngBits = PngBits.png_16 """PNG bit resolution of the Camera Sensor.""" - wavelength_range = field(default_factory=WavelengthsRangeParameters) + wavelength_range: WavelengthsRangeParameters = field(default_factory=WavelengthsRangeParameters) """Wavelength range of the Camera Sensor.""" acquisition_integration_time: float = 0.01 """Integration Time value for the Camera Sensor.""" @@ -258,7 +258,7 @@ class CameraSensorParameters: class ColorimetricParameters: """Colorimetric settings of the Sensor.""" - wavelength_range = field(default_factory=WavelengthsRangeParameters) + wavelength_range: WavelengthsRangeParameters = field(default_factory=WavelengthsRangeParameters) """Wavelength range of the Sensor.""" @@ -266,7 +266,7 @@ class ColorimetricParameters: class SpectralParameters: """Colorimetric settings of the Sensor.""" - wavelength_range = field(default_factory=WavelengthsRangeParameters) + wavelength_range: WavelengthsRangeParameters = field(default_factory=WavelengthsRangeParameters) """Wavelength range of the Sensor.""" From 2fe86cdbd230680d4f8ad66bd868542ceef6b696 Mon Sep 17 00:00:00 2001 From: sthoene Date: Thu, 2 Oct 2025 13:48:44 +0200 Subject: [PATCH 43/47] fix default values --- src/ansys/speos/core/generic/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index d4344d959..d8767f126 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -374,7 +374,7 @@ class Irradiance3DSensorParameters: SensorTypes.photometric ) """Type of the sensor.""" - measures = field(default_factory=MeasuresParameters) + measures: MeasuresParameters = field(default_factory=MeasuresParameters) """Measurement activation state.""" integration_type: Union[IntegrationTypes.planar, IntegrationTypes.radial] = ( IntegrationTypes.planar From 43d46a21ce58b588b28365afd99f06113b5172bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Th=C3=B6ne?= <86405327+StefanThoene@users.noreply.github.com> Date: Tue, 7 Oct 2025 11:11:48 +0200 Subject: [PATCH 44/47] Apply suggestions from code review Co-authored-by: Pengyuan LU <89462462+pluAtAnsys@users.noreply.github.com> --- src/ansys/speos/core/generic/constants.py | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index d8767f126..152992f18 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -113,15 +113,15 @@ class LayerBySequenceParameters: class GeometryLayerParameters: """Geometry layer parameters.""" - name: str - geometry: list + name: Optional[str] = None + geometry: Optional[list] = None @dataclass class LayerByFaceParameters: """Layer separation type Parameters for Face separation.""" - geometries: list[GeometryLayerParameters] = None + geometries: Optional[list[GeometryLayerParameters]] = None sca_filtering_types: Union[ SCAFilteringTypes.intersected_one_time, SCAFilteringTypes.last_impact ] = SCAFilteringTypes.last_impact @@ -185,11 +185,11 @@ class ColorParameters: BalanceModeDisplayPrimariesParameters, ] = ColorBalanceModeTypes.none """Camera Balance mode.""" - red_spectrum_file_uri: str = "" + red_spectrum_file_uri: Union[str, Path] = "" """Path to sensitivity spectrum of red Channel.""" - green_spectrum_file_uri: str = "" + green_spectrum_file_uri: Union[str, Path] = "" """Path to sensitivity spectrum of green Channel.""" - blue_spectrum_file_uri: str = "" + blue_spectrum_file_uri: Union[str, Path] = "" """Path to sensitivity spectrum of blue Channel.""" @@ -197,7 +197,7 @@ class ColorParameters: class MonoChromaticParameters: """Monochromatic Camera Parameters.""" - sensitivity: str = "" + sensitivity: Union[str, Path] = "" """Path to Sensitivity Spectrum.""" @@ -251,7 +251,7 @@ class CameraSensorParameters: """Default height of the camera chip.""" trajectory_fil_uri: Union[str, Path] = "" """Trajectory file information.""" - lxp_path_number: Union[None, int] = None + lxp_path_number: Optional[int] = None @dataclass @@ -321,9 +321,9 @@ class IrradianceSensorParameters: SensorTypes.photometric, ColorimetricParameters, SpectralParameters, SensorTypes.radiometric ] = SensorTypes.photometric """Type of the sensor.""" - integration_type: Union[IntegrationTypes] = IntegrationTypes.planar + integration_type: IntegrationTypes = IntegrationTypes.planar """Integration type of the sensor.""" - integration_direction: Union[None, list[float]] = None + integration_direction: Optional[list[float]] = None """Integration direction of the sensor.""" rayfile_type: Union[RayfileTypes] = RayfileTypes.none """Type of rayfile stored by the sensor.""" @@ -334,7 +334,7 @@ class IrradianceSensorParameters: LayerByIncidenceAngleParameters, ] = LayerTypes.none """Type of layer separation used by the sensor.""" - outpath_face_geometry: list = None + outpath_face_geometry: Optional[list] = None """Outpath face used by the sensor""" @@ -384,5 +384,5 @@ class Irradiance3DSensorParameters: """Rayfile type stored.""" layer_type: Union[LayerTypes.none, LayerTypes.by_source] = LayerTypes.none """Layer separation type.""" - geometries: list = None + geometries: Optional[list] = None """Sensor geometry.""" From 5909ee9a0968d80d34cdef845289e0f39ea55e05 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 09:12:01 +0000 Subject: [PATCH 45/47] ci: auto fixes from pre-commit.com hooks. for more information, see https://pre-commit.ci --- src/ansys/speos/core/generic/constants.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 152992f18..ccd8fc1b9 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -185,11 +185,11 @@ class ColorParameters: BalanceModeDisplayPrimariesParameters, ] = ColorBalanceModeTypes.none """Camera Balance mode.""" - red_spectrum_file_uri: Union[str, Path] = "" + red_spectrum_file_uri: Union[str, Path] = "" """Path to sensitivity spectrum of red Channel.""" - green_spectrum_file_uri: Union[str, Path] = "" + green_spectrum_file_uri: Union[str, Path] = "" """Path to sensitivity spectrum of green Channel.""" - blue_spectrum_file_uri: Union[str, Path] = "" + blue_spectrum_file_uri: Union[str, Path] = "" """Path to sensitivity spectrum of blue Channel.""" From 3f824e46309625ce272f22e05568d01d849dcb20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Th=C3=B6ne?= <86405327+StefanThoene@users.noreply.github.com> Date: Tue, 7 Oct 2025 11:13:35 +0200 Subject: [PATCH 46/47] Update src/ansys/speos/core/generic/constants.py --- src/ansys/speos/core/generic/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index ccd8fc1b9..7b194dca2 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -26,7 +26,7 @@ from enum import Enum import os from pathlib import Path -from typing import Union +from typing import Union, Optional DEFAULT_HOST: str = "localhost" """Default host used by Speos RPC server and client """ From a2004e59738b35488ad18fc9bc1f626a983929f0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 09:14:15 +0000 Subject: [PATCH 47/47] ci: auto fixes from pre-commit.com hooks. for more information, see https://pre-commit.ci --- src/ansys/speos/core/generic/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/speos/core/generic/constants.py b/src/ansys/speos/core/generic/constants.py index 7b194dca2..734d57f13 100644 --- a/src/ansys/speos/core/generic/constants.py +++ b/src/ansys/speos/core/generic/constants.py @@ -26,7 +26,7 @@ from enum import Enum import os from pathlib import Path -from typing import Union, Optional +from typing import Optional, Union DEFAULT_HOST: str = "localhost" """Default host used by Speos RPC server and client """