Download this example
Download this example as a Jupyter Notebook or as a Python script. All assets used in the examples can be downloaded as a ZIP archive.
How to create a component#
This tutorial demonstrates how to create a component feature.
Component feature includes: lightbox import.
Prerequisites#
Perform imports#
[1]:
import json
from pathlib import Path
[2]:
from ansys.speos.core import OptProp, Project, Speos, launcher
from ansys.speos.core.component import LightBox, LightBoxFileInstance
from ansys.speos.core.kernel.client import (
default_docker_channel,
)
from ansys.speos.core.simulation import SimulationDirect
from ansys.speos.core.source import SourceSurface
Define constants#
The constants help ensure consistency and avoid repetition throughout the example.
[3]:
HOSTNAME = "localhost"
GRPC_PORT = 50098 # Be sure the Speos GRPC Server has been started on this port.
USE_DOCKER = True # Set to False if you're running this example locally as a Notebook.
FILES = "CameraInputFiles"
Define helper functions#
These helpers keep LightBox output concise for documentation. Detailed nested content is truncated because it is not the focus of this example.
[4]:
def _truncate_json_value(value, *, max_depth=3, max_list_items=8, max_dict_items=12, _depth=0):
"""Truncate nested JSON-like data for readable output.
Parameters
----------
value : Any
Input value to truncate.
max_depth : int, default: 3
Maximum nesting depth to keep.
max_list_items : int, default: 8
Maximum number of items kept per list.
max_dict_items : int, default: 12
Maximum number of keys kept per dictionary.
_depth : int, default: 0
Current recursion depth. This parameter is for internal use.
Returns
-------
Any
Truncated representation of the input value.
"""
if _depth >= max_depth:
if isinstance(value, dict):
return {"...": f"{len(value)} keys hidden"}
if isinstance(value, list):
return [f"... {len(value)} items hidden"]
return value
if isinstance(value, dict):
items = list(value.items())
out = {
key: _truncate_json_value(
sub_value,
max_depth=max_depth,
max_list_items=max_list_items,
max_dict_items=max_dict_items,
_depth=_depth + 1,
)
for key, sub_value in items[:max_dict_items]
}
hidden = len(items) - max_dict_items
if hidden > 0:
out["..."] = f"{hidden} more keys"
return out
if isinstance(value, list):
out = [
_truncate_json_value(
item,
max_depth=max_depth,
max_list_items=max_list_items,
max_dict_items=max_dict_items,
_depth=_depth + 1,
)
for item in value[:max_list_items]
]
hidden = len(value) - max_list_items
if hidden > 0:
out.append(f"... {hidden} more items")
return out
return value
def print_lightbox_compact(lightbox, *, max_depth=3, max_list_items=8):
"""Print a compact LightBox representation.
Parameters
----------
lightbox : ansys.speos.core.component.LightBox
LightBox feature to print.
max_depth : int, default: 3
Maximum nesting depth kept in the printed JSON payload.
max_list_items : int, default: 8
Maximum number of items shown per list in the printed payload.
Returns
-------
None
This function prints formatted output and returns nothing.
Notes
-----
The optional ``"local: "`` prefix from ``str(lightbox)`` is preserved.
"""
out_str = str(lightbox)
prefix = ""
payload = out_str
if out_str.startswith("local: "):
prefix = "local: "
payload = out_str[len(prefix) :]
try:
payload_dict = json.loads(payload)
except json.JSONDecodeError:
# Fallback to default string output if it is not valid JSON.
print(out_str)
return
compact_payload = _truncate_json_value(
payload_dict,
max_depth=max_depth,
max_list_items=max_list_items,
)
print(prefix + json.dumps(compact_payload, indent=4))
Model Setup#
Load assets#
The assets used to run this example are available in the PySpeos repository on GitHub.
Note: Make sure you have downloaded the simulation assets and set
assets_data_pathto point to the assets’ folder.
[5]:
if USE_DOCKER: # Running on the remote server.
assets_data_path = Path("/app") / "assets"
else:
assets_data_path = Path("/path/to/your/download/assets/directory")
Connect to the RPC Server#
This Python client connects to a server where the Speos engine is running as a service. In this example, the server and client are the same machine. The launch_local_speos_rpc_method can be used to start a local instance of the service.
[6]:
if USE_DOCKER:
speos = Speos(channel=default_docker_channel())
else:
speos = launcher.launch_local_speos_rpc_server(port=GRPC_PORT)
/home/runner/work/pyspeos/pyspeos/.venv/lib/python3.14/site-packages/ansys/tools/common/cyberchannel.py:188: UserWarning: Starting gRPC client without TLS on localhost:50098. This is INSECURE. Consider using a secure connection.
warn(f"Starting gRPC client without TLS on {target}. This is INSECURE. Consider using a secure connection.")
Create a new project#
The only way to create a lightbox import, is to create it from a project.
[7]:
p = Project(speos=speos)
print(p)
{
"name": "",
"description": "",
"metadata": {},
"part_guid": "",
"sub_scene_anchor_axis_system": [],
"sources": [],
"sensors": [],
"simulations": [],
"materials": [],
"scenes": []
}
Create#
Create locally
The mention “local: “ is added when printing the lightbox
[8]:
lightbox = p.create_lightbox(
name="Light Box Import.1",
lightbox=LightBoxFileInstance(
file=assets_data_path / "lightbox" / "Light Box Export.2.SPEOSLightBox", password=""
),
)
print_lightbox_compact(lightbox)
local: {
"name": "Light Box Import.1",
"axis_system": [
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
"... 4 more items"
],
"display_name": "",
"description": "",
"metadata": {},
"scene_guid": "",
"trajectory_file_uri": ""
}
Push it to the server.#
Now that it is committed to the server, the mention “local: “ is no more present when printing the lightbox.
[9]:
lightbox.commit()
print_lightbox_compact(lightbox)
{
"name": "Light Box Import.1",
"metadata": {
"UniqueId": "ea5a201c-4922-409c-ba1b-6969c50f4392"
},
"scene_guid": "4c37b1cf-ccbd-4d7b-8e54-6c5a0dcafaf4",
"axis_system": [
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
"... 4 more items"
],
"display_name": "",
"description": "",
"trajectory_file_uri": "",
"scene": {
"name": "Light Box Export.2",
"description": "From Speos Light Box: /app/assets/lightbox/Light Box Export.2.SPEOSLightBox",
"part_guid": "b1e4bd74-c421-4461-9c11-68c1f1289626",
"sources": [
{
"...": "7 keys hidden"
}
],
"materials": [
{
"...": "8 keys hidden"
}
],
"metadata": {},
"sub_scene_anchor_axis_system": [],
"sensors": [],
"simulations": [],
"scenes": [],
"part": {
"name": "RootPart",
"body_guids": [
"... 1 items hidden"
],
"description": "",
"metadata": {
"...": "0 keys hidden"
},
"parts": [
"... 0 items hidden"
],
"bodys": [
"... 1 items hidden"
]
}
}
}
Read#
Lightbox Instance#
Properties methods provided are used to retrieve or modify the information of lightbox.
[10]:
print(lightbox.name)
print(lightbox.axis_system)
print(lightbox.source_paths)
print(lightbox.trajectory_file_uri)
lightbox.axis_system = [100, 50, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]
print_lightbox_compact(lightbox)
Light Box Import.1
[0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
['Light Box Import.1/Surface.2:1']
{
"name": "Light Box Import.1",
"metadata": {
"UniqueId": "ea5a201c-4922-409c-ba1b-6969c50f4392"
},
"scene_guid": "4c37b1cf-ccbd-4d7b-8e54-6c5a0dcafaf4",
"axis_system": [
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
"... 4 more items"
],
"display_name": "",
"description": "",
"trajectory_file_uri": "",
"scene": {
"name": "Light Box Export.2",
"description": "From Speos Light Box: /app/assets/lightbox/Light Box Export.2.SPEOSLightBox",
"part_guid": "b1e4bd74-c421-4461-9c11-68c1f1289626",
"sources": [
{
"...": "7 keys hidden"
}
],
"materials": [
{
"...": "8 keys hidden"
}
],
"metadata": {},
"sub_scene_anchor_axis_system": [],
"sensors": [],
"simulations": [],
"scenes": [],
"part": {
"name": "RootPart",
"body_guids": [
"... 1 items hidden"
],
"description": "",
"metadata": {
"...": "0 keys hidden"
},
"parts": [
"... 0 items hidden"
],
"bodys": [
"... 1 items hidden"
]
}
}
}
Commit the modification to the server
[11]:
lightbox.commit()
print_lightbox_compact(lightbox)
{
"name": "Light Box Import.1",
"metadata": {
"UniqueId": "ea5a201c-4922-409c-ba1b-6969c50f4392"
},
"scene_guid": "4c37b1cf-ccbd-4d7b-8e54-6c5a0dcafaf4",
"axis_system": [
100.0,
50.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
"... 4 more items"
],
"display_name": "",
"description": "",
"trajectory_file_uri": "",
"scene": {
"name": "Light Box Export.2",
"description": "From Speos Light Box: /app/assets/lightbox/Light Box Export.2.SPEOSLightBox",
"part_guid": "b1e4bd74-c421-4461-9c11-68c1f1289626",
"sources": [
{
"...": "7 keys hidden"
}
],
"materials": [
{
"...": "8 keys hidden"
}
],
"metadata": {},
"sub_scene_anchor_axis_system": [],
"sensors": [],
"simulations": [],
"scenes": [],
"part": {
"name": "RootPart",
"body_guids": [
"... 1 items hidden"
],
"description": "",
"metadata": {
"...": "0 keys hidden"
},
"parts": [
"... 0 items hidden"
],
"bodys": [
"... 1 items hidden"
]
}
}
}
Source and Bodies instance inside Lightbox#
Find method is provided to select the features, e.g. sources, bodies inside lightbox.
Example source in lightbox:
[12]:
lightbox_source = lightbox.find(name=".*", name_regex=True, feature_type=SourceSurface)[0]
print(lightbox_source)
{
"name": "Surface.2:1",
"metadata": {
"UniqueId": "7c2a1d57-4e42-4636-aa55-a42e1e24c904"
},
"source_guid": "4e77526d-6e3d-4642-87e2-cf9ef62e9421",
"display_name": "",
"description": "",
"source": {
"name": "Surface.2:1",
"surface": {
"radiant_flux": {
"radiant_value": 41.275308514008174
},
"intensity_guid": "efaf3ff7-6664-49d5-8e0e-8515a6142538",
"exitance_constant": {
"geo_paths": [
{
"geo_path": "Surface_source2:1796887610/face.1:3037138295",
"reverse_normal": false
}
]
},
"spectrum_guid": "4dff1f43-f8a5-418b-bb79-80ef012debfa",
"intensity": {
"cos": {
"N": 1.0,
"total_angle": 180.0
},
"name": "",
"description": "",
"metadata": {}
},
"spectrum": {
"blackbody": {
"temperature": 2856.0
},
"name": "",
"description": "",
"metadata": {}
}
},
"description": "",
"metadata": {}
}
}
Example material property in lightbox:
[13]:
lightbox_material = lightbox.find(name=".*", name_regex=True, feature_type=OptProp)[0]
print(lightbox_material)
{
"name": "Material.2",
"metadata": {
"UniqueId": "69972af9-83db-4234-b069-776f8f3d73f8"
},
"geometries": {
"geo_paths": [
"Surface_source2:1796887610/face.1:3037138295"
]
},
"sop_guid": "542795fe-b021-455a-b6af-5e27d08d32af",
"display_name": "",
"description": "",
"sop_guids": [],
"sop": {
"mirror": {
"reflectance": 100.0
},
"name": "",
"description": "",
"metadata": {}
},
"sops": [
{
"mirror": {
"reflectance": 100.0
},
"name": "",
"description": "",
"metadata": {}
}
]
}
Modify lightbox features#
feature instance modify method#
The Lightbox contains features that can be modified via feature commit.
[14]:
lightbox_source = lightbox.find(name=".*", name_regex=True, feature_type=SourceSurface)[0]
print(lightbox_source)
lightbox_source.flux.value = 30
lightbox_source.commit()
print(lightbox_source)
{
"name": "Surface.2:1",
"metadata": {
"UniqueId": "7c2a1d57-4e42-4636-aa55-a42e1e24c904"
},
"source_guid": "4e77526d-6e3d-4642-87e2-cf9ef62e9421",
"display_name": "",
"description": "",
"source": {
"name": "Surface.2:1",
"surface": {
"radiant_flux": {
"radiant_value": 41.275308514008174
},
"intensity_guid": "efaf3ff7-6664-49d5-8e0e-8515a6142538",
"exitance_constant": {
"geo_paths": [
{
"geo_path": "Surface_source2:1796887610/face.1:3037138295",
"reverse_normal": false
}
]
},
"spectrum_guid": "4dff1f43-f8a5-418b-bb79-80ef012debfa",
"intensity": {
"cos": {
"N": 1.0,
"total_angle": 180.0
},
"name": "",
"description": "",
"metadata": {}
},
"spectrum": {
"blackbody": {
"temperature": 2856.0
},
"name": "",
"description": "",
"metadata": {}
}
},
"description": "",
"metadata": {}
}
}
{
"name": "Surface.2:1",
"metadata": {
"UniqueId": "7c2a1d57-4e42-4636-aa55-a42e1e24c904"
},
"source_guid": "4e77526d-6e3d-4642-87e2-cf9ef62e9421",
"display_name": "",
"description": "",
"source": {
"name": "Surface.2:1",
"surface": {
"radiant_flux": {
"radiant_value": 30.0
},
"intensity_guid": "efaf3ff7-6664-49d5-8e0e-8515a6142538",
"exitance_constant": {
"geo_paths": [
{
"geo_path": "Surface_source2:1796887610/face.1:3037138295",
"reverse_normal": false
}
]
},
"spectrum_guid": "4dff1f43-f8a5-418b-bb79-80ef012debfa",
"intensity": {
"cos": {
"N": 1.0,
"total_angle": 180.0
},
"name": "",
"description": "",
"metadata": {}
},
"spectrum": {
"blackbody": {
"temperature": 2856.0
},
"name": "",
"description": "",
"metadata": {}
}
},
"description": "",
"metadata": {}
}
}
lightbox instance as global modify method#
The Lightbox contains features that can be modified via lightbox commit.
[15]:
lightbox_material = lightbox.find(name=".*", name_regex=True, feature_type=OptProp)[0]
print(lightbox_material)
lightbox_material.sop_mirror.reflectance = 85
print(lightbox_source)
lightbox_source.intensity.set_cos().total_angle = 20
lightbox.commit()
print(lightbox_material)
print(lightbox_source)
{
"name": "Material.2",
"metadata": {
"UniqueId": "69972af9-83db-4234-b069-776f8f3d73f8"
},
"geometries": {
"geo_paths": [
"Surface_source2:1796887610/face.1:3037138295"
]
},
"sop_guid": "542795fe-b021-455a-b6af-5e27d08d32af",
"display_name": "",
"description": "",
"sop_guids": [],
"sop": {
"mirror": {
"reflectance": 100.0
},
"name": "",
"description": "",
"metadata": {}
},
"sops": [
{
"mirror": {
"reflectance": 100.0
},
"name": "",
"description": "",
"metadata": {}
}
]
}
{
"name": "Surface.2:1",
"metadata": {
"UniqueId": "7c2a1d57-4e42-4636-aa55-a42e1e24c904"
},
"source_guid": "4e77526d-6e3d-4642-87e2-cf9ef62e9421",
"display_name": "",
"description": "",
"source": {
"name": "Surface.2:1",
"surface": {
"radiant_flux": {
"radiant_value": 30.0
},
"intensity_guid": "efaf3ff7-6664-49d5-8e0e-8515a6142538",
"exitance_constant": {
"geo_paths": [
{
"geo_path": "Surface_source2:1796887610/face.1:3037138295",
"reverse_normal": false
}
]
},
"spectrum_guid": "4dff1f43-f8a5-418b-bb79-80ef012debfa",
"intensity": {
"cos": {
"N": 1.0,
"total_angle": 180.0
},
"name": "",
"description": "",
"metadata": {}
},
"spectrum": {
"blackbody": {
"temperature": 2856.0
},
"name": "",
"description": "",
"metadata": {}
}
},
"description": "",
"metadata": {}
}
}
{
"name": "Material.2",
"metadata": {
"UniqueId": "69972af9-83db-4234-b069-776f8f3d73f8"
},
"geometries": {
"geo_paths": [
"Surface_source2:1796887610/face.1:3037138295"
]
},
"sop_guid": "542795fe-b021-455a-b6af-5e27d08d32af",
"display_name": "",
"description": "",
"sop_guids": [],
"sop": {
"mirror": {
"reflectance": 85.0
},
"name": "",
"description": "",
"metadata": {}
},
"sops": [
{
"mirror": {
"reflectance": 85.0
},
"name": "",
"description": "",
"metadata": {}
}
]
}
{
"name": "Surface.2:1",
"metadata": {
"UniqueId": "7c2a1d57-4e42-4636-aa55-a42e1e24c904"
},
"source_guid": "4e77526d-6e3d-4642-87e2-cf9ef62e9421",
"display_name": "",
"description": "",
"source": {
"name": "Surface.2:1",
"surface": {
"radiant_flux": {
"radiant_value": 30.0
},
"intensity_guid": "efaf3ff7-6664-49d5-8e0e-8515a6142538",
"exitance_constant": {
"geo_paths": [
{
"geo_path": "Surface_source2:1796887610/face.1:3037138295",
"reverse_normal": false
}
]
},
"spectrum_guid": "4dff1f43-f8a5-418b-bb79-80ef012debfa",
"intensity": {
"cos": {
"N": 1.0,
"total_angle": 20.0
},
"name": "",
"description": "",
"metadata": {}
},
"spectrum": {
"blackbody": {
"temperature": 2856.0
},
"name": "",
"description": "",
"metadata": {}
}
},
"description": "",
"metadata": {}
}
}
[16]:
# ## Delete
lightbox_source.delete()
[16]:
<ansys.speos.core.source.SourceSurface at 0x7f02fb9a38c0>
Lightbox sources in simulation#
The project contains two lightbox features. source_paths are in format of lightbox_name/source_name.
[17]:
p2 = Project(
speos=speos,
path=assets_data_path / "lightbox" / "Direct.1.speos",
)
lightboxes = p2.find(name=".*", name_regex=True, feature_type=LightBox)
lightbox_1 = lightboxes[0]
lightbox_2 = lightboxes[1]
print(lightbox_1.source_paths)
print(lightbox_2.source_paths)
['3/Surface.1:258']
['Light Box Import.2/Surface.2:1', 'Light Box Import.2/Ray-file.1:12']
Adding lightbox sources in simulation#
User can add all the sources from lightbox using source_paths method Alternatively, user can choose to add selected features
[18]:
sim = p2.find(name=".*", name_regex=True, feature_type=SimulationDirect)[0]
sim.source_paths = lightbox_2.source_paths
sim.commit()
lightbox_source = lightbox_2.find(name=".*", name_regex=True, feature_type=SourceSurface)[0]
sim.source_paths = [lightbox_source]
sim.commit()
[18]:
<ansys.speos.core.simulation.SimulationDirect at 0x7f02b0ff9550>
Black Lightbox#
The Black Lightbox is a lightbox which does not show any features’ information. All sources, geometries, materials information cannot be viewed and cannot be edited.
[19]:
lightbox2 = p.create_lightbox(
name="Light Box Import.2",
lightbox=LightBoxFileInstance(
file=assets_data_path / "lightbox" / "BlackLightBox.SPEOSLightBox", password=""
),
)
print_lightbox_compact(lightbox2)
print(lightbox2.name)
print(lightbox2.source_paths)
local: {
"name": "Light Box Import.2",
"axis_system": [
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
1.0,
"... 4 more items"
],
"display_name": "",
"description": "",
"metadata": {},
"scene_guid": "",
"trajectory_file_uri": ""
}
Light Box Import.2
[]
Add a black lightbox to simulation needs to add lightbox to the source paths.
[20]:
lightbox_3 = p2.create_lightbox(
name="Black Light Box Import",
lightbox=LightBoxFileInstance(
file=assets_data_path / "lightbox" / "BlackLightBox.SPEOSLightBox", password=""
),
)
lightbox_3.commit()
sim.source_paths = [lightbox_3.name]
sim.commit()
[20]:
<ansys.speos.core.simulation.SimulationDirect at 0x7f02b0ff9550>
Download this example
Download this example as a Jupyter Notebook or as a Python script. All assets used in the examples can be downloaded as a ZIP archive.