Skip to content

Commit 5ed8f21

Browse files
authored
Bugfixes (#200)
2 parents 0ed84bf + 3ec0d92 commit 5ed8f21

18 files changed

Lines changed: 651 additions & 338 deletions

artist/core/heliostat_ray_tracer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,8 @@ def trace_rays(
456456
flux_distributions = torch.empty(
457457
(
458458
int(active_heliostats_mask.sum()),
459-
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_e]),
460459
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_u]),
460+
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_e]),
461461
),
462462
device=device,
463463
)
@@ -746,8 +746,8 @@ def get_bitmaps_per_target(
746746
group_bitmaps_per_target = torch.zeros(
747747
(
748748
int(self.scenario.solar_tower.number_of_target_areas_per_type.sum()),
749-
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_e]),
750749
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_u]),
750+
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_e]),
751751
),
752752
device=device,
753753
)

artist/core/kinematics_reconstructor.py

Lines changed: 75 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def __init__(
6767
optimization_configuration: dict[str, Any],
6868
dni: float | None = None,
6969
reconstruction_method: str = config_dictionary.kinematics_reconstruction_raytracing,
70+
bitmap_resolution: torch.Tensor = torch.tensor([256, 256]),
7071
) -> None:
7172
"""
7273
Initialize the kinematics optimizer.
@@ -86,6 +87,9 @@ def __init__(
8687
Direct normal irradiance in W/m^2 (default is None which leads to a ray magnitude of 1.0).
8788
reconstruction_method : str
8889
The reconstruction method. Currently, only reconstruction via ray tracing is implemented.
90+
bitmap_resolution : torch.Tensor
91+
The resolution of all bitmaps during reconstruction (default is ``torch.tensor([256, 256])``).
92+
Shape is ``[2]``.
8993
"""
9094
rank = ddp_setup["rank"]
9195
if rank == 0:
@@ -97,6 +101,7 @@ def __init__(
97101
self.optimizer_dict = optimization_configuration[config_dictionary.optimization]
98102
self.scheduler_dict = optimization_configuration[config_dictionary.scheduler]
99103
self.dni = dni
104+
self.bitmap_resolution = bitmap_resolution
100105

101106
if reconstruction_method in [
102107
config_dictionary.kinematics_reconstruction_raytracing,
@@ -240,6 +245,7 @@ def _reconstruct_kinematics_parameters_with_raytracing(
240245
heliostat_data_mapping=heliostat_mapping,
241246
heliostat_group=heliostat_group,
242247
scenario=self.scenario,
248+
bitmap_resolution=self.bitmap_resolution,
243249
device=device,
244250
)
245251

@@ -250,7 +256,7 @@ def _reconstruct_kinematics_parameters_with_raytracing(
250256
)
251257
focal_spots_measured = utils.bitmap_coordinates_to_target_coordinates(
252258
bitmap_coordinates=focal_spots_bitmap_coordinates,
253-
bitmap_resolution=torch.tensor([256, 256], device=device),
259+
bitmap_resolution=self.bitmap_resolution,
254260
solar_tower=self.scenario.solar_tower,
255261
target_area_indices=target_area_indices,
256262
device=device,
@@ -260,70 +266,79 @@ def _reconstruct_kinematics_parameters_with_raytracing(
260266
initial_actuator_params = (
261267
heliostat_group.kinematics.actuators.optimizable_parameters.detach()
262268
)
263-
264-
angle_mean = initial_actuator_params[
265-
:, index_mapping.actuator_params_initial_angle
266-
].mean()
267-
angle_std = (
268-
initial_actuator_params[
269+
if initial_actuator_params is not None:
270+
angle_mean = initial_actuator_params[
269271
:, index_mapping.actuator_params_initial_angle
270-
]
271-
.std()
272-
.clamp(min=1e-3)
273-
)
272+
].mean()
273+
angle_std = (
274+
initial_actuator_params[
275+
:, index_mapping.actuator_params_initial_angle
276+
]
277+
.std()
278+
.clamp(min=1e-3)
279+
)
274280

275-
stroke_mean = initial_actuator_params[
276-
:, index_mapping.actuator_params_initial_stroke_length
277-
].mean()
278-
stroke_std = (
279-
initial_actuator_params[
281+
stroke_mean = initial_actuator_params[
280282
:, index_mapping.actuator_params_initial_stroke_length
281-
]
282-
.std()
283-
.clamp(min=1e-3)
284-
)
285-
286-
angle_normalized = (
287-
initial_actuator_params[
288-
:, index_mapping.actuator_params_initial_angle
289-
]
290-
- angle_mean
291-
) / angle_std
292-
stroke_length_normalized = (
293-
initial_actuator_params[
294-
:, index_mapping.actuator_params_initial_stroke_length
295-
]
296-
- stroke_mean
297-
) / stroke_std
283+
].mean()
284+
stroke_std = (
285+
initial_actuator_params[
286+
:, index_mapping.actuator_params_initial_stroke_length
287+
]
288+
.std()
289+
.clamp(min=1e-3)
290+
)
298291

299-
delta_angle = torch.zeros_like(angle_normalized, requires_grad=True)
300-
delta_stroke = torch.zeros_like(
301-
stroke_length_normalized, requires_grad=True
302-
)
292+
angle_normalized = (
293+
initial_actuator_params[
294+
:, index_mapping.actuator_params_initial_angle
295+
]
296+
- angle_mean
297+
) / angle_std
298+
stroke_length_normalized = (
299+
initial_actuator_params[
300+
:, index_mapping.actuator_params_initial_stroke_length
301+
]
302+
- stroke_mean
303+
) / stroke_std
304+
305+
delta_angle = torch.zeros_like(angle_normalized, requires_grad=True)
306+
delta_stroke = torch.zeros_like(
307+
stroke_length_normalized, requires_grad=True
308+
)
309+
else:
310+
delta_angle = None
311+
delta_stroke = None
303312

304313
# Set up optimizer, scheduler, and early stopping.
305-
optimizer = torch.optim.Adam(
306-
[
307-
{
308-
"params": heliostat_group.kinematics.rotation_deviation_parameters.requires_grad_(),
309-
"lr": self.optimizer_dict[
310-
config_dictionary.initial_learning_rate_rotation_deviation
311-
],
312-
},
313-
{
314-
"params": delta_angle,
315-
"lr": self.optimizer_dict[
316-
config_dictionary.initial_learning_rate_initial_angles
317-
],
318-
},
319-
{
320-
"params": delta_stroke,
321-
"lr": self.optimizer_dict[
322-
config_dictionary.initial_learning_rate_initial_stroke_length
323-
],
324-
},
325-
]
326-
)
314+
optimizer_params = [
315+
{
316+
"params": heliostat_group.kinematics.rotation_deviation_parameters.requires_grad_(),
317+
"lr": self.optimizer_dict[
318+
config_dictionary.initial_learning_rate_rotation_deviation
319+
],
320+
}
321+
]
322+
323+
if initial_actuator_params is not None:
324+
optimizer_params.extend(
325+
[
326+
{
327+
"params": delta_angle,
328+
"lr": self.optimizer_dict[
329+
config_dictionary.initial_learning_rate_initial_angles
330+
],
331+
},
332+
{
333+
"params": delta_stroke,
334+
"lr": self.optimizer_dict[
335+
config_dictionary.initial_learning_rate_initial_stroke_length
336+
],
337+
},
338+
]
339+
)
340+
341+
optimizer = torch.optim.Adam(optimizer_params)
327342

328343
# Create a learning rate scheduler.
329344
scheduler_fn = getattr(
@@ -408,6 +423,7 @@ def _reconstruct_kinematics_parameters_with_raytracing(
408423
batch_size=self.optimizer_dict[config_dictionary.batch_size],
409424
random_seed=self.ddp_setup["heliostat_group_rank"],
410425
dni=self.dni,
426+
bitmap_resolution=self.bitmap_resolution,
411427
)
412428

413429
# Perform heliostat-based ray tracing.

artist/core/loss_functions.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,13 @@ def __call__(
203203

204204
focal_spot_coordinates = utils.bitmap_coordinates_to_target_coordinates(
205205
bitmap_coordinates=focal_spots_bitmap,
206-
bitmap_resolution=torch.tensor(prediction.shape[1:]),
206+
bitmap_resolution=torch.tensor(
207+
[
208+
prediction.shape[index_mapping.batched_bitmap_u],
209+
prediction.shape[index_mapping.batched_bitmap_e],
210+
],
211+
device=device,
212+
),
207213
solar_tower=self.scenario.solar_tower,
208214
target_area_indices=target_area_indices,
209215
device=device,

artist/core/motor_position_optimizer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,8 @@ def optimize(
371371

372372
total_flux = torch.zeros(
373373
(
374-
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_e]),
375374
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_u]),
375+
int(self.bitmap_resolution[index_mapping.unbatched_bitmap_e]),
376376
),
377377
device=device,
378378
)

artist/data_parser/paint_calibration_parser.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,9 @@ def _parse_calibration_data(
260260
target_area_mapping = torch.empty(
261261
total_samples, device=device, dtype=torch.long
262262
)
263-
focal_spots_global = torch.empty((total_samples, 3), device=device)
263+
focal_spots_global = torch.empty(
264+
(total_samples, 3), dtype=torch.float64, device=device
265+
)
264266
azimuths = torch.empty(total_samples, device=device)
265267
elevations = torch.empty(total_samples, device=device)
266268
motor_positions = torch.empty((total_samples, 2), device=device)
@@ -275,7 +277,9 @@ def _parse_calibration_data(
275277
motor_pos,
276278
) in calibration_data_per_heliostat.get(name, []):
277279
target_area_mapping[index] = target_index
278-
focal_spots_global[index] = torch.tensor(focal_spot, device=device)
280+
focal_spots_global[index] = torch.tensor(
281+
focal_spot, dtype=torch.float64, device=device
282+
)
279283
azimuths[index] = azimuth
280284
elevations[index] = elevation
281285
motor_positions[index] = torch.tensor(motor_pos, device=device)

artist/scenario/scenario.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ def load_scenario_from_hdf5(
146146
power_plant_position = torch.tensor(
147147
scenario_file[config_dictionary.power_plant_key][
148148
config_dictionary.power_plant_position
149-
][()]
149+
][()],
150+
dtype=torch.float64,
151+
device=device,
150152
)
151153

152154
solar_tower = SolarTower.from_hdf5(config_file=scenario_file, device=device)

0 commit comments

Comments
 (0)