Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
- name: Install dependencies
run: |
source .venv/bin/activate
uv pip install ty==0.0.25 ansys-platform-instancemanagement
uv pip install ty==0.0.25 ansys-platform-instancemanagement ansys-speos-core[graphics]

# NOTE: At the moment this will only run on ansys/aedt/core/speos.py which is working
- name: Run Ty on selected files
Expand All @@ -108,7 +108,6 @@ jobs:
--exclude src/ansys/speos/core/simulation.py \
--exclude src/ansys/speos/core/sensor.py \
--exclude src/ansys/speos/core/__init__.py \
--exclude src/ansys/speos/core/generic \
--exclude src/ansys/speos/core/kernel \
--exclude src/ansys/speos/core/workflow \
--exclude examples/core \
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/911.maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve typing generic
16 changes: 8 additions & 8 deletions src/ansys/speos/core/generic/file_transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

import ansys.api.speos.file.v1.file_transfer_pb2 as file_transfer__v1__pb2
import ansys.api.speos.file.v1.file_transfer_pb2_grpc as file_transfer__v1__pb2_grpc
import grpc
from grpc import _channel

from ansys.speos.core.generic.version_checker import server_version_checker
from ansys.speos.core.kernel.client import SpeosClient
Expand Down Expand Up @@ -69,7 +69,7 @@ def _file_to_chunks(self, file, file_name, chunk_size=4000000):

if first_chunk:
if self._is_gte_26r1:
chunk.file_name = file_name
chunk.file_name = file_name # ty: ignore
first_chunk = False

yield chunk
Expand All @@ -95,7 +95,7 @@ def upload_file(
Contains for example file uri and upload duration.
"""
if not file_path.exists() or not file_path.is_file():
raise ValueError("Incorrect file_path : " + file_path)
raise ValueError("Incorrect file_path : " + str(file_path))

with file_path.open("rb") as file:
chunk_iterator = self._file_to_chunks(file, file_path.name)
Expand All @@ -109,7 +109,7 @@ def upload_file(

try:
return self._file_transfer_service_stub.Upload(chunk_iterator, metadata=metadata)
except grpc._channel._InactiveRpcError as e:
except _channel._InactiveRpcError as e:
err = (
'"file_name" field in Chunk is missing or "reserved-file-uri"'
+ " key/value not provided in ClientContext's metadata"
Expand Down Expand Up @@ -144,11 +144,11 @@ def upload_folder(
Contains for example file uri and upload duration.
"""
if not folder_path.exists() or not folder_path.is_dir():
raise ValueError("Incorrect folder_path : " + folder_path)
raise ValueError("Incorrect folder_path : " + str(folder_path))

main_file_path = folder_path / main_file_name
if not main_file_path.exists() or not main_file_path.is_file():
raise ValueError("Incorrect main_file_path : " + main_file_path)
raise ValueError("Incorrect main_file_path : " + str(main_file_path))

upload_responses = []
add_dependencies_request = file_transfer__v1__pb2.AddDependencies_Request()
Expand Down Expand Up @@ -217,7 +217,7 @@ def download_file(
"""
start_time = datetime.datetime.now()
if not download_location.exists() or not download_location.is_dir():
raise ValueError("Incorrect download_location : " + download_location)
raise ValueError("Incorrect download_location : " + str(download_location))

chunks = self._file_transfer_service_stub.Download(
file_transfer__v1__pb2.Download_Request(uri=file_uri)
Expand Down Expand Up @@ -281,7 +281,7 @@ def download_folder(
Contains for example file uri, file name, file size and download duration.
"""
if not download_location.exists() or not download_location.is_dir():
raise ValueError("Incorrect download_location : " + download_location)
raise ValueError("Incorrect download_location : " + str(download_location))

response = []

Expand Down
14 changes: 8 additions & 6 deletions src/ansys/speos/core/generic/general_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from functools import lru_cache, wraps
import os
from pathlib import Path
from typing import List, Optional, Union, cast
from typing import List, Optional, Tuple, Union, cast
import warnings

from ansys.tools.common.path import get_available_ansys_installations
Expand Down Expand Up @@ -184,7 +184,7 @@ def error_no_install(install_path: Union[Path, str], version: Union[int, str]) -
Always raised to signal a missing Speos RPC installation.
"""
raise FileNotFoundError(
f"Ansys Speos RPC server installation not found at {install_path}. "
f"Ansys Speos RPC server installation not found at {str(install_path)}. "
f"Please define AWP_ROOT{version} environment variable. "
)

Expand Down Expand Up @@ -245,9 +245,11 @@ def retrieve_speos_install_dir(
installations.get(int(version)) # dict keys are int
or os.environ.get(f"AWP_ROOT{version}") # fallback: env var
)
if not ansys_loc:
if ansys_loc:
path = Path(ansys_loc) / "Optical Products" / "SPEOS_RPC"
else:
error_no_install(speos_rpc_path or "<unset>", int(version))
path = Path(ansys_loc) / "Optical Products" / "SPEOS_RPC"
path = Path() # for type checker; this line is never reached

# --- verify executable exists -----------------------------------------
speos_exec = path / ("SpeosRPC_Server.exe" if os.name == "nt" else "SpeosRPC_Server.x")
Expand All @@ -257,7 +259,7 @@ def retrieve_speos_install_dir(
return path


def wavelength_to_rgb(wavelength: float, gamma: float = 0.8) -> [int, int, int, int]:
def wavelength_to_rgb(wavelength: float, gamma: float = 0.8) -> Tuple[int, int, int, int]:
"""Convert a given wavelength of light to an approximate RGB color value.

The wavelength must be given in nanometers in the range from 380 nm to 750 nm.
Expand Down Expand Up @@ -305,7 +307,7 @@ def wavelength_to_rgb(wavelength: float, gamma: float = 0.8) -> [int, int, int,
r *= 255
g *= 255
b *= 255
return [int(r), int(g), int(b), 255]
return (int(r), int(g), int(b), 255)


def min_speos_version(major: int, minor: int, service_pack: int):
Expand Down
51 changes: 30 additions & 21 deletions src/ansys/speos/core/generic/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import datetime
from enum import Enum
from pathlib import Path
from typing import Optional, Union
from typing import Literal, Optional, Union

from ansys.speos.core.generic.constants import ORIGIN

Expand Down Expand Up @@ -137,7 +137,7 @@ class LayerBySequenceParameters:

maximum_nb_of_sequence: int = 10
"""Maximum number of sequencese stored in Speos Result file"""
sequence_type: Union[SequenceTypes.by_face, SequenceTypes.by_geometry] = (
sequence_type: Union[Literal[SequenceTypes.by_face], Literal[SequenceTypes.by_geometry]] = (
SequenceTypes.by_geometry
)
"""Defines how sequences are calculated"""
Expand All @@ -160,7 +160,7 @@ class LayerByFaceParameters:
geometries: Optional[list[GeometryLayerParameters]] = None
"""List of Geometry Layers"""
sca_filtering_types: Union[
SCAFilteringTypes.intersected_one_time, SCAFilteringTypes.last_impact
Literal[SCAFilteringTypes.intersected_one_time], Literal[SCAFilteringTypes.last_impact]
] = SCAFilteringTypes.last_impact
"""Defines how data result data is filtered"""

Expand Down Expand Up @@ -218,8 +218,8 @@ class ColorParameters:
"""Color mode Camera Parameter."""

balance_mode: Union[
ColorBalanceModeTypes.none,
ColorBalanceModeTypes.grey_world,
Literal[ColorBalanceModeTypes.none],
Literal[ColorBalanceModeTypes.grey_world],
BalanceModeUserWhiteParameters,
BalanceModeDisplayPrimariesParameters,
] = ColorBalanceModeTypes.none
Expand Down Expand Up @@ -248,7 +248,7 @@ class PhotometricCameraParameters:
default_factory=ColorParameters
)
"""Color mode of the Camera Sensor."""
layer_type: Union[LayerTypes.none, LayerTypes.by_source] = LayerTypes.none
layer_type: Union[Literal[LayerTypes.none], Literal[LayerTypes.by_source]] = LayerTypes.none
"""Layer separation parameter."""
png_bits: PngBits = PngBits.png_16
"""PNG bit resolution of the Camera Sensor."""
Expand Down Expand Up @@ -374,7 +374,10 @@ class IrradianceSensorParameters:
axis_system: list[float] = field(default_factory=lambda: ORIGIN)
"""Position of the sensor."""
sensor_type: Union[
SensorTypes.photometric, ColorimetricParameters, SpectralParameters, SensorTypes.radiometric
Literal[SensorTypes.photometric],
Literal[SensorTypes.radiometric],
ColorimetricParameters,
SpectralParameters,
] = SensorTypes.photometric
"""Type of the sensor."""
integration_type: IntegrationTypes = IntegrationTypes.planar
Expand All @@ -384,9 +387,9 @@ class IrradianceSensorParameters:
rayfile_type: Union[RayfileTypes] = RayfileTypes.none
"""Type of rayfile stored by the sensor."""
layer_type: Union[
LayerTypes.none,
LayerTypes.by_source,
LayerTypes.by_polarization,
Literal[LayerTypes.none],
Literal[LayerTypes.by_source],
Literal[LayerTypes.by_polarization],
LayerByFaceParameters,
LayerBySequenceParameters,
LayerByIncidenceAngleParameters,
Expand All @@ -405,7 +408,10 @@ class RadianceSensorParameters:
axis_system: list[float] = field(default_factory=lambda: ORIGIN)
"""Position of the sensor."""
sensor_type: Union[
SensorTypes.photometric, ColorimetricParameters, SpectralParameters, SensorTypes.radiometric
Literal[SensorTypes.photometric],
Literal[SensorTypes.radiometric],
ColorimetricParameters,
SpectralParameters,
] = SensorTypes.photometric
"""Type of the sensor."""
focal_length: float = 250.0
Expand All @@ -416,8 +422,8 @@ class RadianceSensorParameters:
observer: Union[None, list[float]] = None
"""The position of the observer point."""
layer_type: Union[
LayerTypes.none,
LayerTypes.by_source,
Literal[LayerTypes.none],
Literal[LayerTypes.by_source],
LayerByFaceParameters,
LayerBySequenceParameters,
] = LayerTypes.none
Expand All @@ -428,19 +434,19 @@ class RadianceSensorParameters:
class Irradiance3DSensorParameters:
"""Parameters class for 3D Irradiance Sensor."""

sensor_type: Union[SensorTypes.photometric, ColorimetricParameters, SensorTypes.radiometric] = (
SensorTypes.photometric
)
sensor_type: Union[
Literal[SensorTypes.photometric], ColorimetricParameters, Literal[SensorTypes.radiometric]
] = SensorTypes.photometric
"""Type of the sensor."""
measures: MeasuresParameters = field(default_factory=MeasuresParameters)
"""Measurement activation state."""
integration_type: Union[IntegrationTypes.planar, IntegrationTypes.radial] = (
integration_type: Union[Literal[IntegrationTypes.planar], Literal[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_type: Union[Literal[LayerTypes.none], Literal[LayerTypes.by_source]] = LayerTypes.none
"""Layer separation type."""
geometries: Optional[list] = None
"""Sensor geometry."""
Expand Down Expand Up @@ -469,16 +475,19 @@ class IntensityXMPSensorParameters:
axis_system: list[float] = field(default_factory=lambda: ORIGIN)
"""Position of the sensor."""
sensor_type: Union[
SensorTypes.photometric, ColorimetricParameters, SpectralParameters, SensorTypes.radiometric
Literal[SensorTypes.photometric],
ColorimetricParameters,
SpectralParameters,
Literal[SensorTypes.radiometric],
] = SensorTypes.photometric
"""Type of the sensor."""
orientation: IntensitySensorOrientationTypes = IntensitySensorOrientationTypes.x_as_meridian
"""Sensor orientation."""
viewing_direction: IntensitySensorViewingTypes = IntensitySensorViewingTypes.from_source
"""Viewing Direction onto the result."""
layer_type: Union[
LayerTypes.none,
LayerTypes.by_source,
Literal[LayerTypes.none],
Literal[LayerTypes.by_source],
LayerByFaceParameters,
LayerBySequenceParameters,
] = LayerTypes.none
Expand Down
32 changes: 20 additions & 12 deletions src/ansys/speos/core/generic/visualization_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

"""Provides the ``VisualData`` class."""

from typing import TYPE_CHECKING, List, Tuple, Union
from typing import TYPE_CHECKING, List, Tuple, Union, cast

import numpy as np

Expand Down Expand Up @@ -239,21 +239,25 @@ def __init__(
raise ValueError(
"line_vertices is expected to be composed of 2 vertices with 3 elements each."
)
line_vertices = np.array(line_vertices)
vertices_array = np.array(line_vertices)
if arrow:
self.__data = pv.Arrow(
start=line_vertices[0],
direction=line_vertices[1],
start=vertices_array[0],
direction=vertices_array[1],
scale=1,
tip_radius=0.05,
shaft_radius=0.01,
)
else:
self.__data = pv.Line(line_vertices[0], line_vertices[0] + line_vertices[1])
self.__data = pv.Line(vertices_array[0], vertices_array[0] + vertices_array[1])
if all(value < 1 for value in color):
self.__color = color + (255,)
self.__color: Tuple[float, float, float, int] = cast(
Tuple[float, float, float, int], color + (255,)
)
else:
self.__color = tuple(value / 255 for value in color) + (255,)
self.__color = cast(
Tuple[float, float, float, int], tuple(value / 255 for value in color) + (255,)
)

@property
def data(self) -> "pv.PolyData":
Expand All @@ -269,13 +273,13 @@ def data(self) -> "pv.PolyData":
return self.__data

@property
def color(self) -> Tuple[float, float, float]:
def color(self) -> Tuple[float, float, float, int]:
"""
Returns the color property of _VisualArrow.

Returns
-------
Tuple[float, float, float]
Tuple[float, float, float, int]
The color tuple of _VisualArrow.

"""
Expand Down Expand Up @@ -334,7 +338,9 @@ def add_data_triangle(self, triangle_vertices: List[List[float]]) -> None:
"triangle_vertices is expected to be composed of 3 vertices with 3 elements each."
)
faces = [[3, 0, 1, 2]]
self._data = self._data.append_polydata(pv.PolyData(triangle_vertices, faces))
self._data = cast("pv.PolyData", self._data).append_polydata(
pv.PolyData(triangle_vertices, faces)
)

def add_data_rectangle(self, rectangle_vertices: List[List[float]]) -> None:
"""
Expand All @@ -355,7 +361,9 @@ def add_data_rectangle(self, rectangle_vertices: List[List[float]]) -> None:
raise ValueError(
"rectangle_vertices is expected to be composed of 3 vertices with 3 elements each."
)
self._data = self._data.append_polydata(pv.Rectangle(rectangle_vertices))
self._data = cast("pv.PolyData", self._data).append_polydata(
pv.Rectangle(rectangle_vertices)
)

def add_data_line(self, line: _VisualArrow) -> None:
"""
Expand Down Expand Up @@ -393,7 +401,7 @@ def add_data_mesh(self, vertices: np.ndarray, facets: np.ndarray) -> None:
raise ValueError(
"mesh vertices is expected to be composed of 3 elements each, and 4 for facets."
)
self._data = self._data.append_polydata(pv.PolyData(vertices, facets))
self._data = cast("pv.PolyData", self._data).append_polydata(pv.PolyData(vertices, facets))


def local2absolute(local_vertice: np.ndarray, coordinates) -> np.ndarray:
Expand Down
Loading