artist.optim
Submodules
Classes
Initialize the kinematics optimizer. |
|
Initialize the angle loss. |
|
Initialize the focal spot loss. |
|
Initialize the Kullback-Leibler divergence loss. |
|
Initialize the base loss. |
|
Initialize the pixel loss. |
|
Initialize the vector loss. |
|
Initialize the motor-positions optimizer. |
|
Initialize the regularizer. |
|
Initialize the regularizer. |
|
Initialize the surface reconstructor. |
|
Initialize the early stopping. |
Functions
|
Calculate the mean loss per heliostat from a loss per sample. |
|
Create a cyclic learning rate scheduler. |
|
Create an exponential learning rate scheduler. |
|
Create learning rate scheduler that reduces on plateaus. |
Package Contents
- class artist.optim.KinematicsReconstructor(ddp_setup: artist.util.env.DdpSetup, scenario: artist.scenario.scenario.Scenario, data: dict[str, artist.io.calibration_parser.CalibrationDataParser | list[tuple[str, list[pathlib.Path], list[pathlib.Path]]]], optimization_configuration: dict[str, Any], dni: float | None = None, reconstruction_method: str = constants.kinematics_reconstruction_raytracing, bitmap_resolution: torch.Tensor = torch.tensor([256, 256]))
Initialize the kinematics optimizer.
Parameters
- ddp_setupDdpSetup
Information about the distributed environment, process groups, devices, ranks, world size, and heliostat-group-to-ranks mapping.
- scenarioScenario
The scenario.
- datadict[str, CalibrationDataParser | list[tuple[str, list[pathlib.Path], list[pathlib.Path]]]]
The data parser and the mapping of heliostat name and calibration data.
- optimization_configurationdict[str, Any]
Parameters for the optimizer, learning rate scheduler, regularizers, and early stopping.
- dnifloat | None
Direct normal irradiance in W/m^2 (default is None which leads to a ray magnitude of 1.0).
- reconstruction_methodstr
The reconstruction method. Currently, only reconstruction via ray tracing is implemented.
- bitmap_resolutiontorch.Tensor
The resolution of all bitmaps during reconstruction (default is
torch.tensor([256, 256])). Shape is[2].
- ddp_setup
- scenario
- data
- optimizer_dict
- scheduler_dict
- dni = None
- bitmap_resolution
- reconstruct_kinematics(loss_definition: artist.optim.loss.Loss, device: torch.device | None = None) tuple[torch.Tensor, list[Any]]
Reconstruct the kinematic parameters.
Parameters
- loss_definitionLoss
The definition of the loss function and pre-processing of the prediction.
- 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
The final loss of the kinematics reconstruction for each heliostat in each group. Shape is
[total_number_of_heliostats_in_scenario].- list[list[dict[str, list[float]]]]
Loss histories over epochs grouped by rank. Outer list: one entry per rank. Inner list: one entry per heliostat group processed on that rank. Each group entry is a dict with key
"total_loss"mapping to a list of per-epoch scalar loss values. In non-distributed mode, this is a single-rank container:[local_group_histories].
- _reconstruct_kinematics_parameters_with_raytracing(loss_definition: artist.optim.loss.Loss, device: torch.device | None = None) tuple[torch.Tensor, list[list[dict[str, list[float]]]]]
Reconstruct the kinematics parameters using ray tracing.
This reconstruction method optimizes the kinematics parameters by extracting the focal points of calibration images and using heliostat-tracing.
Parameters
- loss_definitionLoss
Definition of the loss function and pre-processing of the prediction.
- 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
The final loss of the kinematics reconstruction for each heliostat in each group. Shape is
[total_number_of_heliostats_in_scenario].- list[list[dict[str, list[float]]]]
Loss histories over epochs grouped by rank. Outer list: one entry per rank. Inner list: one entry per heliostat group processed on that rank. Each group entry is a dict with key
"total_loss"mapping to a list of per-epoch scalar loss values. In non-distributed mode, this is a single-rank container:[local_group_histories].
- class artist.optim.AngleLoss
Bases:
LossInitialize the angle loss.
- __call__(prediction: torch.Tensor, ground_truth: torch.Tensor, **kwargs: Any) torch.Tensor
Compute the cosine similarity between the prediction and ground truth.
Parameters
- predictiontorch.Tensor
The predicted values. Shape is
[number_of_samples, 4].- ground_truthtorch.Tensor
The ground truth. Shape is
[number_of_samples, 4].- **kwargsAny
Keyword arguments.
Returns
- torch.Tensor
The summed loss reduced along the specified dimensions. Shape is
[number_of_samples].
- class artist.optim.FocalSpotLoss(scenario: artist.scenario.scenario.Scenario)
Bases:
LossInitialize the focal spot loss.
Parameters
- scenarioScenario
The scenario.
- scenario
- __call__(prediction: torch.Tensor, ground_truth: torch.Tensor, **kwargs: Any) torch.Tensor
Compute the focal spot loss.
First the focal spots of the prediction are computed, then the loss is computed and reduced along the specified dimensions.
Parameters
- predictiontorch.Tensor
The predicted values. Shape is
[number_of_samples, bitmap_resolution_e, bitmap_resolution_u].- ground_truthtorch.Tensor
The ground truth. Shape is
[number_of_samples, 4].- **kwargsAny
Keyword arguments.
target_area_indicesanddeviceare expected keyword arguments for the focal spot loss.
Raises
- ValueError
If expected keyword arguments are not passed.
Returns
- torch.Tensor
The focal spot loss. Shape is
[number_of_samples].
- class artist.optim.KLDivergenceLoss
Bases:
LossInitialize the Kullback-Leibler divergence loss.
- __call__(prediction: torch.Tensor, ground_truth: torch.Tensor, **kwargs: Any) torch.Tensor
Compute the Kullback-Leibler divergence loss \(D_{\mathrm{KL}}(P \parallel Q)\).
The elements in the prediction and ground truth are normalized and shifted, to be greater or equal to zero. The KL-divergence is defined by:
\[D_{\mathrm{KL}}(P \parallel Q) = \sum_{x} P(x) \log \frac{P(x)}{Q(x)},\]where \(P\) is the ground truth distribution and \(Q\) is the approximation or prediction of \(Q\). The KL-divergence is an asymmetric function. Switching \(P\) and \(Q\) has the following effect: \(P \parallel Q\) Penalizes extra mass in the prediction where the ground truth has none. \(Q \parallel P\) Penalizes missing mass in the prediction where the ground truth has mass.
Parameters
- predictiontorch.Tensor
The predicted values. Shape is
[number_of_samples, bitmap_resolution_e, bitmap_resolution_u].- ground_truthtorch.Tensor
The ground truth. Shape is
[number_of_samples, bitmap_resolution_e, bitmap_resolution_u].- **kwargsAny
Keyword arguments.
reduction_dimensionsis an expected keyword argument for the KL-divergence loss.
Raises
- ValueError
If expected keyword arguments are not passed.
Returns
- torch.Tensor
The summed KL-divergence loss reduced along the specified dimensions. Shape is
[number_of_samples].
- class artist.optim.Loss(loss_function: torch.nn.Module)
Initialize the base loss.
Parameters
- loss_functiontorch.nn.Module
A torch module implementing a loss.
- loss_function
- abstractmethod __call__(prediction: torch.Tensor, ground_truth: torch.Tensor, **kwargs: Any) torch.Tensor
Compute the loss.
Parameters
- predictiontorch.Tensor
The predicted values. Shape is variable.
- ground_truthtorch.Tensor
The ground truth. Shape is variable.
- **kwargsAny
Keyword arguments.
Raises
- NotImplementedError
This abstract method must be overridden.
- class artist.optim.PixelLoss(scenario: artist.scenario.scenario.Scenario)
Bases:
LossInitialize the pixel loss.
Parameters
- scenarioScenario
The scenario.
- scenario
- __call__(prediction: torch.Tensor, ground_truth: torch.Tensor, **kwargs: Any) torch.Tensor
Compute the pixel loss.
First the predicted bitmaps and the ground truth are normalized, then the loss is computed and reduced along the specified dimensions.
Parameters
- predictiontorch.Tensor
The predicted values. Shape is
[number_of_samples, bitmap_resolution_e, bitmap_resolution_u].- ground_truthtorch.Tensor
The ground truth. Shape is
[number_of_samples, bitmap_resolution_e, bitmap_resolution_u].- **kwargsAny
Keyword arguments.
reduction_dimensions,target_area_indices, anddeviceare expected keyword arguments for the pixel loss.
Raises
- ValueError
If expected keyword arguments are not passed.
Returns
- torch.Tensor
The summed MSE pixel loss reduced along the specified dimensions. Shape is
[number_of_samples].
- class artist.optim.VectorLoss
Bases:
LossInitialize the vector loss.
- __call__(prediction: torch.Tensor, ground_truth: torch.Tensor, **kwargs: Any) torch.Tensor
Compute the vector loss.
Parameters
- predictiontorch.Tensor
The predicted values. Shape is
[number_of_samples, ...].- ground_truthtorch.Tensor
The ground truth. Shape is
[number_of_samples, ...].- **kwargsAny
Keyword arguments.
reduction_dimensionsis an expected keyword argument for the vector loss.
Raises
- ValueError
If expected keyword arguments are not passed.
Returns
- torch.Tensor
The summed MSE vector loss reduced along the specified dimensions. Shape is
[number_of_samples].
- artist.optim.mean_loss_per_heliostat(loss_per_sample: torch.Tensor, number_of_samples_per_heliostat: int) torch.Tensor
Calculate the mean loss per heliostat from a loss per sample.
Parameters
- loss_per_sampletorch.Tensor
Loss per sample. Shape is
[number_of_samples].- number_of_samples_per_heliostatint
Number of samples per heliostat.
Returns
- torch.Tensor
Loss per heliostat. Shape is
[number_of_heliostats].
- class artist.optim.MotorPositionsOptimizer(ddp_setup: artist.util.env.DdpSetup, scenario: artist.scenario.scenario.Scenario, optimization_configuration: dict[str, Any], incident_ray_direction: torch.Tensor, target_area_index: int, ground_truth: torch.Tensor, dni: float, bitmap_resolution: torch.Tensor = torch.tensor([256, 256]), epsilon: float = 1e-12, device: torch.device | None = None)
Initialize the motor-positions optimizer.
Parameters
- ddp_setupDdpSetup
Information about the distributed environment, process groups, devices, ranks, world size, and heliostat-group-to-ranks mapping.
- scenarioScenario
The scenario.
- optimization_configurationdict[str, Any]
Parameters for the optimizer, learning rate scheduler, regularizers, and early stopping.
- incident_ray_directiontorch.Tensor
Incident ray direction during the optimization. Shape is
[4].- target_area_indexint
Index of the target used for the optimization.
- ground_truthtorch.Tensor
Desired focal spot or distribution. Shape is
[4]or[bitmap_resolution_e, bitmap_resolution_u].- dnifloat
Direct normal irradiance in W/m^2.
- bitmap_resolutiontorch.Tensor
Resolution of all bitmaps during optimization (default is
torch.tensor([256,256])). Shape is[2].- epsilonfloat
A small value to avoid division by zero (default is 1e-12).
- devicetorch.device | None
The device on which to perform computations or load tensors and models (default is None). If None,
ARTISTwill automatically select the most appropriate device (CUDA or CPU) based on availability and OS.
- ddp_setup
- scenario
- optimizer_dict
- scheduler_dict
- constraint_dict
- incident_ray_direction
- target_area_index
- ground_truth
- dni
- bitmap_resolution
- epsilon = 1e-12
- optimize(loss_definition: artist.optim.loss.Loss, device: torch.device | None = None) tuple[torch.Tensor, dict[str, list], torch.Tensor, torch.Tensor, torch.Tensor]
Optimize the motor positions.
The motor positions are optimized through a reparameterization to ensure stable training across different heliostats with widely varying initial motor positions and ranges. Motor positions can range from 0 to up to ~80000. Instead of directly optimizing the absolute motor positions, which can differ in magnitudes, an unconstrained parameter is optimized. Directly optimizing the absolute motor positions would have very different effects depending on the scale of the motors. For small initial motor positions (e.g. ~100), a gradient update of size 10 may cause a ~10% relative change, drastically altering the motor positions of this heliostat. For large initial motor positions (e.g. ~50000), the same optimizer step would correspond to only a 0.02% relative change in motor positions, effectively freezing the optimization of this heliostat. This mismatch makes it impossible to choose a single learning rate that works robustly across all heliostats. Reparameterizing the motor positions to be optimized defines the optimizable parameter as:
\[\text{motor\_positions\_optimized} = \tanh( \text{torch.nn.Parameter(optimizable\_parameter)} )\]The true motor positions can be reconstructed by:
\[\text{motor\_positions} = \text{initial\_motor\_positions} + \text{motor\_positions\_normalized} \cdot \text{scale}\]where scale defines the range (e.g. up to ~80000) for adjustments. By optimizing reparameterized instead of raw motor positions, every heliostat sees updates of comparable relative magnitude, regardless of the absolute size of its motors positions.
Parameters
- loss_definitionLoss
The definition of the loss function and pre-processing of the prediction.
- devicetorch.device | None
The device on which to perform computations or load tensors and models (default is None). If None,
ARTISTwill automatically select the most appropriate device (CUDA or CPU) based on availability and OS.
Returns
- torch.Tensor
Final loss of the motor position optimization.
- dict[str, list]
Loss history over epochs, with keys
"total_loss","flux_loss","local_flux_constraint","intercept_constraint","flux_integral_constraint", and"flux_integral". Each value is a list of per-epoch scalar floats.- torch.Tensor
Final intercept factors for each heliostat.
- torch.Tensor
Final fraction of rays hitting the target, neglecting blocking effects, for each heliostat.
- torch.Tensor
Final fraction of rays not being blocked, for each heliostat.
- class artist.optim.IdealSurfaceRegularizer(reduction_dimensions: tuple[int, Ellipsis])
Bases:
RegularizerInitialize the regularizer.
Parameters
- reduction_dimensionstuple[int, …]
Dimensions along which to reduce the loss.
- __call__(current_control_points: torch.Tensor, original_control_points: torch.Tensor, device: torch.device | None = None, **kwargs: Any) torch.Tensor
Compute the L2 loss between current control points and original control points.
Parameters
- current_control_pointstorch.Tensor
The current control points. Shape is
[number_of_heliostats, number_of_facets_per_surface, number_of_control_points_u_direction, number_of_control_points_v_direction, 3].- original_control_pointstorch.Tensor
The current control points. Shape is
[number_of_heliostats, number_of_facets_per_surface, number_of_control_points_u_direction, number_of_control_points_v_direction, 3].- devicetorch.device | None
The device on which to perform computations or load tensors and models (default is None). If None,
ARTISTwill automatically select the most appropriate device (CUDA or CPU) based on availability and OS.
Returns
- torch.Tensor
L2 deviation loss per surface.
- class artist.optim.SmoothnessRegularizer(reduction_dimensions: tuple[int, Ellipsis])
Bases:
RegularizerInitialize the regularizer.
Parameters
- reduction_dimensionstuple[int, …]
Dimensions along which to reduce the loss.
- __call__(current_control_points: torch.Tensor, original_control_points: torch.Tensor, device: torch.device | None = None, **kwargs: Any) torch.Tensor
Compute the Laplacian regularization loss.
The loss measures how much each control-point displacement differs from the average of its four immediate neighbors, thereby penalizing localized, non-smooth deformations.
Parameters
- current_control_pointstorch.Tensor
The current control points. Shape is
[number_of_heliostats, number_of_facets_per_surface, number_of_control_points_u_direction, number_of_control_points_v_direction, 3].- original_control_pointstorch.Tensor
The original control points. Shape is
[number_of_heliostats, number_of_facets_per_surface, number_of_control_points_u_direction, number_of_control_points_v_direction, 3].- devicetorch.device | None
The device on which to perform computations or load tensors and models (default is None). If None,
ARTISTwill automatically select the most appropriate device (CUDA or CPU) based on availability and OS.
Returns
- torch.Tensor
Laplacian regularization loss per surface.
- class artist.optim.SurfaceReconstructor(ddp_setup: artist.util.env.DdpSetup, scenario: artist.scenario.scenario.Scenario, data: dict[str, artist.io.calibration_parser.CalibrationDataParser | list[tuple[str, list[pathlib.Path], list[pathlib.Path]]]], optimization_configuration: dict[str, Any], dni: float | None = None, number_of_surface_points: torch.Tensor = torch.tensor([50, 50]), bitmap_resolution: torch.Tensor = torch.tensor([256, 256]), epsilon: float | None = 1e-12, device: torch.device | None = None)
Initialize the surface reconstructor.
Parameters
- ddp_setupDdpSetup
Information about the distributed environment, process groups, devices, ranks, world size, and heliostat-group-to-ranks mapping.
- scenarioScenario
The scenario.
- datadict[str, CalibrationDataParser | list[tuple[str, list[pathlib.Path], list[pathlib.Path]]]]
The data parser and the mapping of heliostat name and calibration data.
- optimization_configurationdict[str, Any]
The parameters for the optimizer, learning rate scheduler, early stopping, and constraints.
- dnifloat | None
Direct normal irradiance in W/m² used to scale the ray-traced flux (default is None). If None, the
HeliostatRayTraceruses its own default.- number_of_surface_pointstorch.Tensor
The number of surface points of the reconstructed surfaces (default is
torch.tensor([50, 50])). Shape is[2].- bitmap_resolutiontorch.Tensor
The resolution of all bitmaps during reconstruction (default is
torch.tensor([256, 256])). Shape is[2].- epsilonfloat | None
Small numerical offset used to avoid division by zero in the energy constraint (default is 1e-12).
- devicetorch.device | None
The device on which to perform computations or load tensors and models (default is None). If None,
ARTISTwill automatically select the most appropriate device (CUDA or CPU) based on availability and OS.
- ddp_setup
- scenario
- data
- optimizer_dict
- scheduler_dict
- constraint_dict
- number_of_surface_points
- dni = None
- bitmap_resolution
- epsilon = 1e-12
- reconstruct_surfaces(loss_definition: artist.optim.loss.Loss, device: torch.device | None = None) tuple[torch.Tensor, list[list[dict[str, list[float]]]]]
Reconstruct NURBS surfaces from bitmaps.
Parameters
- loss_definitionLoss
The definition of the loss function and pre-processing of the prediction.
- devicetorch.device | None
The device on which to perform computations or load tensors and models (default is None). If None,
ARTISTwill automatically select the most appropriate device (CUDA or CPU) based on availability and OS.
Returns
- torch.Tensor
The final reconstruction loss per heliostat, one entry per heliostat in the scenario. Shape is
[total_number_of_heliostats_in_scenario].- list[list[dict[str, list[float]]]]
Loss histories over epochs grouped by rank.
Outer list: one entry per rank.
Inner list: one entry per heliostat group processed on that rank.
Each group entry is a dict with keys:
"total_loss","flux_loss","smoothness_regularizer","ideal_regularizer","flux_integral", and"flux_integral_constraint". Each value is a list of per-epoch scalar floats.In non-distributed mode, this is a single-rank container:
[local_group_histories].
- static lock_control_points_on_outer_edges(gradients: torch.Tensor, device: torch.device | None = None) torch.Tensor
Lock the u and v values of the control points on the outer edges of each facet.
As the knots of the first and last knots on each facet have full multiplicity, the NURBS surfaces all start and end in control points. If the outer control points are not fixed in their u and v values, the reconstructed surfaces may not be rectangular anymore. To keep them rectangular, this function zeros the gradients of the u and v coordinates of all outer control points.
Parameters
- gradientstorch.Tensor
The full control point gradient tensor for all active heliostats. Gradients on the outer edges will be zeroed; interior gradients are returned unchanged. Shape is
[number_of_active_heliostats, number_of_facets_per_surface, number_of_control_points_u_direction, number_of_control_points_v_direction, 3].- devicetorch.device | None
The device on which to perform computations or load tensors and models (default is None). If None,
ARTISTwill automatically select the most appropriate device (CUDA or CPU) based on availability and OS.
Returns
- torch.Tensor
The updated gradients. Shape is
[number_of_active_heliostats, number_of_facets_per_surface, number_of_control_points_u_direction, number_of_control_points_v_direction, 3].
- class artist.optim.EarlyStopping(window_size: int = 10, patience: int = 20, min_improvement: float = 0.0001, relative: bool = True, eps: float = 1e-08)
Initialize the early stopping.
Parameters
- window_sizeint
Number of epochs used to estimate loss trend (default is 10).
- patienceint
Number of consecutive non-improving windows before stopping (default is 20).
- min_improvementfloat
Minimum required improvement over the window to reset patience (default is 1e-4).
- relativebool
Indicates whether improvement is normalized by loss magnitude (default is True).
- epsfloat
Small value for stability (default is 1e-8).
- window_size = 10
- patience = 20
- min_improvement = 0.0001
- relative = True
- eps = 1e-08
- loss_history: Deque[float]
- counter = 0
- artist.optim.cyclic(optimizer: torch.optim.Optimizer, parameters: dict[str, float]) torch.optim.lr_scheduler.LRScheduler
Create a cyclic learning rate scheduler.
Parameters
- optimizerOptimizer
The optimizer.
- parametersdict[str, float]
The scheduler parameters.
Returns
- LRScheduler
A cyclic learning rate scheduler.
- artist.optim.exponential(optimizer: torch.optim.Optimizer, parameters: dict[str, float]) torch.optim.lr_scheduler.LRScheduler
Create an exponential learning rate scheduler.
Parameters
- optimizerOptimizer
The optimizer.
- parametersdict[str, float]
The scheduler parameters.
Returns
- LRScheduler
An exponential learning rate scheduler.
- artist.optim.reduce_on_plateau(optimizer: torch.optim.Optimizer, parameters: dict[str, float]) torch.optim.lr_scheduler.LRScheduler
Create learning rate scheduler that reduces on plateaus.
Parameters
- optimizerOptimizer
The optimizer.
- parametersdict[str, float]
The scheduler parameters.
Returns
- LRScheduler
A learning rate scheduler that reduces on plateaus.