artist.raytracing

Submodules

Classes

HeliostatRayTracer

Initialize the heliostat ray tracer.

DistortionsDataset

Initialize the dataset.

RestrictedDistributedSampler

Set up a custom distributed sampler to assign data to each rank or leave them idle.

Functions

line_cylinder_intersections(, device, torch.Tensor, ...)

Compute ray intersections with cylindrical receiver target areas and map hits into bitmap coordinates.

line_plane_intersections(, device, torch.Tensor, ...)

Compute line-plane intersections of the rays (lines) and the target areas (planes).

reflect(→ torch.Tensor)

Reflect incoming rays given the normals of reflective surfaces.

Package Contents

artist.raytracing.line_cylinder_intersections(rays: artist.scene.rays.Rays, points_at_ray_origins: torch.Tensor, target_areas: artist.field.tower_target_areas_cylindrical.TowerTargetAreasCylindrical, target_area_indices: torch.Tensor | None = None, bitmap_resolution: torch.Tensor = torch.tensor([256, 256]), device: torch.device | None = None) tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]

Compute ray intersections with cylindrical receiver target areas and map hits into bitmap coordinates.

This routine transforms rays from world space into each target cylinder’s local frame, computes intersections with the infinite cylinder side surface, filters intersections to the finite cylinder sector (height + opening angle), and returns per-ray bitmap coordinates, intersection distances, and Lambert-weighted intensities.

Pipeline:

  1. Select target area per heliostat (or default to index 0).

  2. Build local cylinder frame and transform ray origins/directions into that frame.

  3. Solve quadratic for intersections with the infinite cylinder (x^2 + y^2 = r^2).

  4. Select the smallest strictly positive intersection distance per ray.

  5. Compute local intersection points, surface normals, and cosine-based intensity factor.

  6. Filter to finite cylinder patch bounds:

    • height range [0, h]

    • angle range [0, opening_angle]

  7. Convert valid local coordinates to continuous bitmap coordinates.

Parameters

raysRays

Rays with directions and magnitudes, the directions must be normalized.

points_at_ray_originstorch.Tensor

Ray origins in world space. Shape is [number_of_active_heliostats, number_of_combined_surface_points_all_facets, 4].

target_areasTowerTargetAreasCylindrical

Cylindrical receiver definitions (centers, axes, normals, radii, heights, opening angles).

target_area_indicestorch.Tensor | None

Indices of target areas corresponding to each heliostat (default is None). If none are provided, the first target area of the scenario will be linked to all heliostats. Shape is [number_of_active_heliostats].

bitmap_resolutiontorch.Tensor

Bitmap resolution (default is torch.tensor([256,256])).

devicetorch.device | None

The device on which to perform computations or load tensors and models (default is None). If None, ARTIST will automatically select the most appropriate device (CUDA or CPU) based on availability and OS.

Returns

torch.Tensor

Continuous E (horizontal/unwrapped-angle) bitmap coordinates in pixel units. Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets]. Invalid rays are 0.

torch.Tensor

Continuous U (vertical/height) bitmap coordinates in pixel units. Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets]. Invalid rays are 0.

torch.Tensor

Ray parameter distance t to the selected cylinder intersection. Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets]. Invalid rays are 0.

torch.Tensor

Lambert-weighted hit intensities: ray_magnitudes * max(0, -dot(ray_dir_local, normal_local)). Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets]. Invalid rays are 0.

artist.raytracing.line_plane_intersections(rays: artist.scene.rays.Rays, points_at_ray_origins: torch.Tensor, target_areas: artist.field.tower_target_areas_planar.TowerTargetAreasPlanar, target_area_indices: torch.Tensor | None = None, bitmap_resolution: torch.Tensor = torch.tensor([256, 256]), device: torch.device | None = None) tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]

Compute line-plane intersections of the rays (lines) and the target areas (planes).

Parameters

raysRays

Rays with directions and magnitudes, the directions must be normalized.

points_at_ray_originstorch.Tensor

Origins of the rays, which coincide with the surface points of the heliostats. Shape is [number_of_active_heliostats, number_of_combined_surface_points_all_facets, 4].

target_areasTowerTargetAreas

All planar tower target areas.

target_area_indicestorch.Tensor | None

Indices of target areas corresponding to each heliostat (default is None). If none are provided, the first target area of the scenario will be linked to all heliostats. Shape is [number_of_active_heliostats].

bitmap_resolutiontorch.Tensor | None

Bitmap resolution (default is torch.tensor([256,256])).

devicetorch.device | None

The device on which to perform computations or load tensors and models (default is None). If None, ARTIST will automatically select the most appropriate device (CUDA or CPU) based on availability and OS.

Returns

torch.Tensor

East components of the bitmap intersections. Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets].

torch.Tensor

Up components of the bitmap intersections. Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets].

torch.Tensor

Intersection distances. Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets].

torch.Tensor

Absolute intensities of the rays hitting the target planes. Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_points_all_facets].

artist.raytracing.reflect(incident_ray_directions: torch.Tensor, reflection_surface_normals: torch.Tensor) torch.Tensor

Reflect incoming rays given the normals of reflective surfaces.

Parameters

incident_ray_directionstorch.Tensor

Direction of the incident ray as seen from the heliostats. Shape is [number_of_active_heliostats, 1, 4].

reflection_surface_normalstorch.Tensor

Normals of the reflective surfaces. Shape is [number_of_active_heliostats, number_of_combined_surface_normals_all_facets, 4].

Returns

torch.Tensor

Reflected rays. Shape is [number_of_active_heliostats, number_of_combined_surface_normals_all_facets, 4].

class artist.raytracing.HeliostatRayTracer(scenario: artist.scenario.scenario.Scenario, heliostat_group: artist.field.heliostat_group.HeliostatGroup, blocking_active: bool = True, world_size: int = 1, rank: int = 0, batch_size: int = 100, random_seed: int = 7, bitmap_resolution: torch.Tensor = torch.tensor([indices.bitmap_resolution, indices.bitmap_resolution]), dni: float | None = None)

Initialize the heliostat ray tracer.

“Heliostat”-tracing is one kind of ray tracing applied in ARTIST. For this kind of ray tracing, the rays are initialized on the heliostats. The rays originate in the discrete surface points. There they are multiplied, distorted, and scattered, and then they are sent to the aim points. Letting the rays originate on the heliostats, drastically reduces the number of rays that need to be traced.

Parameters

scenarioScenario

The scenario used to perform ray tracing.

heliostat_groupHeliostatGroup

The selected heliostat group containing active heliostats.

blocking_activebool

Flag indicating whether blocking is activated (default is True).

world_sizeint

The world size, i.e., the overall number of processes (default is 1).

rankint

The rank, i.e., individual process ID (default is 0).

batch_sizeint

The number of samples (heliostats) processed in parallel within a single rank (default is 100).

random_seedint

The random seed used for generating the distortions (default is 7).

bitmap_resolutiontorch.Tensor

The resolution of the bitmap in both directions. (default is torch.tensor([256,256])). Shape is [2].

dnifloat | None

Direct normal irradiance in W/m^2 (default is None -> ray magnitude = 1.0).

scenario
heliostat_group
blocking_active = True
world_size = 1
rank = 0
batch_size = 100
light_source
distortions_dataset
distortions_sampler
distortions_loader
bitmap_resolution
get_sampler_indices() torch.Tensor

Get the indices assigned to the current rank by the distributed sampler.

Returns

torch.Tensor

Indices of the distortions dataset that are assigned to this rank. Shape is [number_of_samples_assigned_to_current_rank].

trace_rays(incident_ray_directions: torch.Tensor, active_heliostats_mask: torch.Tensor, target_area_indices: torch.Tensor, ray_extinction_factor: float = 0.0, mirror_reflectivity: float = 0.935, device: torch.device | None = None) tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]

Perform heliostat ray tracing.

Scatter the rays according to the distortions, calculate the intersections with the target planes, and sample the resulting bitmaps on the target areas. The bitmaps are generated separately for each active heliostat and are accessed individually. If blocking is activated in the HeliostatRayTracer, rays that are blocked by other heliostats are filtered out.

Parameters

incident_ray_directionstorch.Tensor

The direction of the incident rays as seen from the heliostats. Shape is [number_of_active_heliostats, 4].

active_heliostats_masktorch.Tensor

A mask where 0 indicates a deactivated heliostat and 1 an activated one. An integer greater than 1 indicates that this heliostat is regarded multiple times. Shape is [number_of_heliostats].

target_area_indicestorch.Tensor

The indices of the target areas for each active heliostat. Shape is [number_of_active_heliostats].

ray_extinction_factorfloat

Amount of global ray extinction, responsible for shading (default is 0.0 -> no extinction).

mirror_reflectivityfloat

Fraction of incident ray intensity reflected by the mirror surface (default is 0.935).

devicetorch.device | None

The device on which to perform computations or load tensors and models (default is None). If None, ARTIST will automatically select the most appropriate device (CUDA or CPU) based on availability and OS.

Raises

ValueError

If not all heliostats used for ray tracing have been aligned.

Returns

torch.Tensor

The resulting bitmaps per heliostat. Shape is [number_of_active_heliostats, bitmap_resolution_e, bitmap_resolution_u].

torch.Tensor

The fraction of rays hitting the target, neglecting blocking effects. Shape is [number_of_active_heliostats].

torch.Tensor

The fraction of rays not being blocked. Shape is [number_of_active_heliostats].

torch.Tensor

The fraction of rays actually hitting the target, taking into account blocking effects. Shape is [number_of_active_heliostats].

scatter_rays(distortion_u: torch.Tensor, distortion_e: torch.Tensor, original_ray_direction: torch.Tensor, device: torch.device | None = None) artist.scene.rays.Rays

Scatter the reflected rays around the preferred ray directions for each heliostat.

Parameters

distortion_utorch.Tensor

The distortions in up direction (angles for scattering). Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_normals_all_facets].

distortion_etorch.Tensor

The distortions in east direction (angles for scattering). Shape is [number_of_active_heliostats, number_of_rays, number_of_combined_surface_normals_all_facets].

original_ray_directiontorch.Tensor

The ray direction around which to scatter. Shape is [number_of_active_heliostats, number_of_combined_surface_normals_all_facets, 4].

devicetorch.device | None

The device on which to perform computations or load tensors and models (default is None). If None, ARTIST will automatically select the most appropriate device (CUDA or CPU) based on availability and OS.

Returns

Rays

Scattered rays around the preferred reflection directions.

get_bitmaps_per_target(bitmaps_per_heliostat: torch.Tensor, target_area_indices: torch.Tensor, device: torch.device | None = None) torch.Tensor

Transform bitmaps per heliostat to bitmaps per target area.

Parameters

bitmaps_per_heliostattorch.Tensor

Bitmaps per heliostat. Shape is [number_of_active_heliostats, bitmap_resolution_e, bitmap_resolution_u].

target_area_indicestorch.Tensor

The mapping from heliostat to target area. Shape is [number_of_active_heliostats].

devicetorch.device | None

The device on which to perform computations or load tensors and models (default is None). If None, ARTIST will automatically select the most appropriate device (CUDA or CPU) based on availability and OS.

Returns

torch.Tensor

Bitmaps per target area. Shape is [number_of_target_areas, bitmap_resolution_e, bitmap_resolution_u].

bilinear_splatting(bitmap_intersections_e: torch.Tensor, bitmap_intersections_u: torch.Tensor, absolute_intensities: torch.Tensor, device: torch.device | None) torch.Tensor

Distribute ray intensities onto bitmap pixels using bilinear splatting.

Each ray intersection with the target area is treated as a continuously positioned value between four neighboring discrete pixels (east/west and up/down neighbors). The intensity is split among these four pixels proportionally to their proximity to the intersection point, yielding a differentiable approximation of the discrete binning operation.

Parameters

bitmap_intersections_etorch.Tensor

The east-component bitmap coordinates of ray intersections. Shape is [number_of_active_heliostats, number_of_rays, number_of_surface_points].

bitmap_intersections_utorch.Tensor

The up-component bitmap coordinates of ray intersections. Shape is [number_of_active_heliostats, number_of_rays, number_of_surface_points].

absolute_intensitiestorch.Tensor

The intensity of each ray at its intersection point. Shape is [number_of_active_heliostats, number_of_rays, number_of_surface_points].

devicetorch.device | None

The device on which to perform computations or load tensors and models. If None, ARTIST will automatically select the most appropriate device (CUDA or CPU) based on availability and OS.

Returns

torch.Tensor

The flux density bitmaps, one per active heliostat. Shape is [number_of_active_heliostats, bitmap_resolution_u, bitmap_resolution_e].

class artist.raytracing.DistortionsDataset(light_source: artist.scene.light_source.LightSource, number_of_points_per_heliostat: int, number_of_active_heliostats: int, random_seed: int = 7)

Bases: torch.utils.data.Dataset

Initialize the dataset.

This class implements a custom dataset according to the torch interface. The content of this dataset are the distortions. The distortions are used in our version of “heliostat”-tracing to indicate how each incoming ray must be multiplied and scattered on the heliostat. According to torch, this dataset must implement a function to return the length of the dataset and one function to retrieve an element through an index.

Parameters

light_sourceLightSource

The light source used to model the distortions.

number_of_points_per_heliostatint

The number of points on the heliostats for which distortions are created.

number_of_active_heliostatsint

The number of active heliostats in the scenario.

random_seedint

The random seed used for generating the distortions (default is 7).

__len__() int

Calculate the length of the dataset, i.e., the number of items contained.

Returns

int

The length of the dataset.

__getitem__(idx: int) tuple[torch.Tensor, torch.Tensor]

Select an item from the dataset.

Parameters

idxint

The index of the item to select.

Returns

torch.Tensor

The distortions in the up direction for the given index.

torch.Tensor

The distortions in the east direction for the given index.

class artist.raytracing.RestrictedDistributedSampler(number_of_samples: int, number_of_active_heliostats: int, world_size: int = 1, rank: int = 0)

Bases: torch.utils.data.Sampler

Set up a custom distributed sampler to assign data to each rank or leave them idle.

Parameters

number_of_samplesint

Length of the dataset or total number of samples.

number_of_active_heliostatsint

Number of active heliostats.

world_sizeint

World size or total number of processes (default is 1).

rankint

Rank of the current process (default is 0).

rank_indices = []
__iter__() Iterator[int]

Generate a sequence of indices for the current rank’s portion of the dataset.

Returns

Iterator[int]

An iterator over indices for the current rank.