Ray Tracing#

The ray-tracing modules handle ray tracing simulations, incident angle calculations, PSF analysis and I/O.

incident_angles#

Calculate photon incident angles on focal plane and primary/secondary mirrors.

Parses the imaging list (.lis) produced by sim_telarray_debug_trace and uses Angle of incidence at focal surface, with respect to the optical axis [deg], Angle of incidence on to primary mirror [deg], and Angle of incidence on to secondary mirror [deg] (if available).

class ray_tracing.incident_angles.IncidentAnglesCalculator(simtel_path, db_config, config_data, output_dir, label=None)[source]#

Run a PSF-style sim_telarray job and compute incident angles at mirrors or focal surfaces.

Parameters:
simtel_pathstr or pathlib.Path

Path to the sim_telarray installation directory (containing sim_telarray/bin).

db_configdict

Database configuration passed to initialize_simulation_models.

config_datadict

Simulation configuration (e.g. site, telescope, model_version, off_axis_angle, source_distance, number_of_photons).

output_dirstr or pathlib.Path

Output directory where logs, scripts, photons files and results are written.

labelstr, optional

Label used to name outputs; defaults to incident_angles_<telescope> when omitted.

Notes

Additional options are read from config_data when present: - perfect_mirror (bool, default False) - calculate_primary_secondary_angles (bool, default True)

run()[source]#

Run sim_telarray, parse the imaging list, and return an angle table.

Returns:
astropy.table.QTable

Table containing at least the angle_incidence_focal column and, when configured, primary/secondary angles and hit geometry.

run_for_offsets(offsets)[source]#

Run the simulation for multiple off-axis angles.

For each off-axis angle provided, run a full simulation, labeling output files accordingly.

Parameters:
offsetsIterable[float]

Off-axis angles in degrees.

Returns:
dict[float, astropy.table.QTable]

Mapping from off-axis angle (deg) to the resulting table.

ray_tracing#

Ray tracing simulations and analysis.

class ray_tracing.ray_tracing.RayTracing(telescope_model, site_model, simtel_path, label=None, zenith_angle=<Quantity 20. deg>, off_axis_angle=<Quantity [0.] deg>, source_distance=<Quantity 10. km>, single_mirror_mode=False, use_random_focal_length=False, random_focal_length_seed=None, mirror_numbers='all')[source]#

Ray tracing simulations and analysis.

Parameters:
telescope_model: TelescopeModel

telescope model

site_model: SiteModel

site model

simtel_path: str (or Path)

Location of sim_telarray installation.

label: str

label used for output file naming.

zenith_angle: astropy.units.Quantity

Zenith angle.

off_axis_angle: list of astropy.units.Quantity

Off-axis angles.

source_distance: astropy.units.Quantity

Source distance.

single_mirror_mode: bool

Single mirror mode flag.

use_random_focal_length: bool

Use random focal length flag.

random_focal_length_seed: int

Seed for the random number generator used for focal length variation.

mirror_numbers: list, str

List of mirror numbers (or ‘all’).

analyze(export=True, force=False, use_rx=False, no_tel_transmission=False, containment_fraction=0.8)[source]#

Ray tracing analysis.

Involves the following: read simtel files, compute PSFs and eff areas, store the results in _results.

Parameters:
export: bool

If True, results will be exported to a file automatically. Alternatively, export_results function can be used.

force: bool

If True, existing results files will be removed and analysis will be done again.

use_rx: bool

If True, calculations are done using the rx binary provided by sim_telarray. If False, calculations are done internally, by the module psf_analysis.

no_tel_transmission: bool

If True, the telescope transmission is not applied.

containment_fraction: float

Containment fraction for PSF containment calculation. Allowed values are in the interval [0,1]

export_results()[source]#

Export results to a csv file.

get_mean(key)[source]#

Get mean value of key.

Parameters:
key: str

d80_cm, d80_deg, eff_area or eff_flen

Returns:
float

Mean value of key.

Raises:
KeyError

If key is not among the valid options.

get_std_dev(key)[source]#

Get std dev of key.

Parameters:
key: str

d80_cm, d80_deg, eff_area or eff_flen

Returns:
float

Std deviation of key.

Raises:
KeyError

If key is not among the valid options.

images()[source]#

Get list of PSFImages.

Returns:
List of PSFImages
plot(key, save=False, d80=None, **kwargs)[source]#

Plot key vs off-axis angle and save the figure in pdf.

Parameters:
key: str

d80_cm, d80_deg, eff_area or eff_flen

save: bool

If True, figure will be saved.

d80: float

d80 for cumulative PSF plot.

**kwargs:

kwargs for plt.plot

Raises:
KeyError

If key is not among the valid options.

plot_histogram(key, **kwargs)[source]#

Plot histogram of key.

Parameters:
key: str

d80_cm, d80_deg, eff_area or eff_flen

**kwargs:

kwargs for plt.hist

Raises:
KeyError

If key is not among the valid options.

simulate(test=False, force=False)[source]#

Simulate RayTracing using SimulatorRayTracing.

Parameters:
test: bool

Test flag will make it faster by simulating much fewer photons.

force: bool

Force flag will remove existing files and simulate again.

psf_analysis#

Module to analyse psf images (e.g. results from ray tracing simulations).

Main functionalities are: computing centroids, psf containers etc.

class ray_tracing.psf_analysis.PSFImage(focal_length=None, total_scattered_area=None, containment_fraction=None, simtel_path=None)[source]#

Image composed of list of photon positions (2D).

Load photon list from sim_telarray file and compute centroids, psf containers, effective area, as well as plot the image as a 2D histogram. Internal units: photon positions in cm internally.

Parameters:
focal_length: float

Focal length of the system in cm. If not given, PSF can only be computed in cm.

total_scattered_area: float

Scatter area of all photons in cm^2. If not given, effective area cannot be computed.

containment_fraction: float

Containment fraction for PSF calculation.

simtel_path: str

Path to sim_telarray installation.

get_cumulative_data(radius=None)[source]#

Provide cumulative data (intensity vs radius).

Parameters:
radius: array

Array with radius calculate the cumulative PSF in distance units.

Returns:
(radius, intensity)
get_effective_area(tel_transmission=1.0)[source]#

Return effective area pre calculated.

Parameters:
telescope_transmissionfloat

Telescope transmission parameter.

Returns:
float

Pre-calculated effective area. None if it could not be calculated (e.g because the total scattering area was not set).

get_image_data(centralized=True)[source]#

Provide image data (2D photon positions in cm) as lists.

Parameters:
centralized: bool

Centroid of the image is set to (0, 0) if True.

Returns:
(x, y), the photons positions in cm.
get_psf(fraction=0.8, unit='cm')[source]#

Return PSF.

Parameters:
fraction: float

Fraction of photons within the containing radius.

unit: str

‘cm’ or ‘deg’. ‘deg’ will not work if focal length was not set.

Returns:
float:

Containing diameter for a certain intensity fraction (PSF).

plot_cumulative(file_name=None, d80=None, **kwargs)[source]#

Plot cumulative data (intensity vs radius).

Parameters:
**kwargs:

image_* for the histogram plot and psf_* for the psf circle.

plot_image(centralized=True, file_name=None, **kwargs)[source]#

Plot 2D image as histogram (in cm).

Parameters:
centralized: bool

Centroid of the image is set to (0, 0) if True.

**kwargs:

image_* for the histogram plot and psf_* for the psf circle.

process_photon_list(photon_file, use_rx)[source]#

Read and process a photon list file generated by sim_telarray.

Parameters:
photons_file: str

Name of sim_telarray file with photon list.

use_rx: bool

Use the RX method for analysis.

read_photon_list_from_simtel_file(photons_file)[source]#

Read photon list file generated by sim_telarray and store the photon positions (2D).

Parameters:
photons_file: str

Name of sim_telarray file with photon list.

Raises:
RuntimeError

If photon positions X and Y are not compatible or are empty.

set_effective_area(value)[source]#

Set effective area.

Parameters:
value: float

Effective area

set_psf(value, fraction=0.8, unit='cm')[source]#

Set PSF calculated from other methods.

Parameters:
value: float

PSF value to be set

fraction: float

Fraction of photons within the containing radius.

unit: str

‘cm’ or ‘deg’. ‘deg’ will not work if focal length was not set.

psf_parameter_optimisation#

PSF parameter optimisation and fitting routines for mirror alignment and reflection parameters.

This module provides functions for loading PSF data, generating random parameter sets, running PSF simulations, calculating RMSD, and finding the best-fit parameters for a given telescope model. PSF (Point Spread Function) describes how a point source of light is spread out by the optical system, and RMSD (Root Mean Squared Deviation) is used as the optimization metric to quantify the difference between measured and simulated PSF curves.

ray_tracing.psf_parameter_optimisation.analyze_monte_carlo_error(tel_model, site_model, args_dict, data_to_plot, radius, n_simulations=500)[source]#

Analyze Monte Carlo uncertainty in PSF optimization metrics.

Runs multiple simulations with the same parameters to quantify the statistical uncertainty in the optimization metric due to Monte Carlo noise in the ray tracing simulations. Returns None values if no measurement data is provided or all simulations fail.

Parameters:
tel_modelTelescopeModel

Telescope model object with current parameter configuration.

site_modelSiteModel

Site model object with environmental conditions.

args_dictdict

Dictionary containing simulation configuration arguments.

data_to_plotdict

Dictionary containing measured PSF data under “measured” key.

radiusarray-like

Radius values in cm for PSF evaluation.

n_simulationsint, optional

Number of Monte Carlo simulations to run (default: 500).

Returns:
tuple of (float, float, list, float, float, list, float, float, list)
  • mean_metric: Mean RMSD or KS statistic value

  • std_metric: Standard deviation of metric values

  • metric_values: List of all metric values from simulations

  • mean_p_value: Mean p-value (None if using RMSD)

  • std_p_value: Standard deviation of p-values (None if using RMSD)

  • p_values: List of all p-values from simulations

  • mean_psf_diameter: Mean PSF containment diameter in cm

  • std_psf_diameter: Standard deviation of PSF diameter values

  • psf_diameter_values: List of all PSF diameter values from simulations

ray_tracing.psf_parameter_optimisation.apply_gradient_step(current_params, gradients, learning_rate)[source]#

Apply gradient descent step to update parameters.

Parameters:
current_paramsdict

Dictionary of current parameter values.

gradientsdict

Dictionary of gradient values for each parameter.

learning_ratefloat

Step size for the gradient descent update.

Returns:
dict

Dictionary of updated parameter values after applying the gradient step.

ray_tracing.psf_parameter_optimisation.calculate_gradient(tel_model, site_model, args_dict, current_params, data_to_plot, radius, current_rmsd, epsilon=0.0005, use_ks_statistic=False)[source]#

Calculate numerical gradients for all optimization parameters.

Parameters:
tel_modelTelescopeModel

Telescope model object for simulations.

site_modelSiteModel

Site model object with environmental conditions.

args_dictdict

Dictionary containing simulation configuration arguments.

current_paramsdict

Dictionary of current parameter values for all optimization parameters.

data_to_plotdict

Dictionary containing measured PSF data.

radiusarray-like

Radius values in cm for PSF evaluation.

current_rmsdfloat

Current RMSD or KS statistic value.

epsilonfloat, optional

Perturbation value for finite difference calculation (default: 0.0005).

use_ks_statisticbool, optional

If True, calculate gradients for KS statistic; if False, use RMSD (default: False).

Returns:
dict

Dictionary mapping parameter names to their gradient values. For parameters with multiple components, gradients are returned as lists.

ray_tracing.psf_parameter_optimisation.calculate_ks_statistic(data, sim)[source]#

Calculate the KS statistic between measured and simulated cumulative PSF curves.

ray_tracing.psf_parameter_optimisation.calculate_rmsd(data, sim)[source]#

Calculate RMSD between measured and simulated cumulative PSF curves.

ray_tracing.psf_parameter_optimisation.export_psf_parameters(best_pars, telescope, parameter_version, output_dir)[source]#

Export optimized PSF parameters as simulation model parameter files.

Parameters:
best_parsdict

Dictionary containing the optimized parameter values.

telescopestr

Telescope name for the parameter files.

parameter_versionstr

Version string for the parameter files.

output_dirPath

Base directory for parameter file output.

Raises:
ValueError, KeyError, OSError

If parameter export fails due to invalid values, missing keys, or file I/O errors.

Notes

Creates individual JSON files for each optimized parameter with units. Files are saved in the format: {output_dir}/{telescope}/{parameter_name}-{parameter_version}.json

ray_tracing.psf_parameter_optimisation.get_previous_values(tel_model)[source]#

Retrieve current PSF parameter values from the telescope model.

Parameters:
tel_modelTelescopeModel

Telescope model object containing parameter configurations.

Returns:
dict

Dictionary containing current values of PSF optimization parameters: - ‘mirror_reflection_random_angle’: Random reflection angle parameters - ‘mirror_align_random_horizontal’: Horizontal alignment parameters - ‘mirror_align_random_vertical’: Vertical alignment parameters

ray_tracing.psf_parameter_optimisation.load_and_process_data(args_dict)[source]#

Load and process PSF measurement data from ECSV file.

Parameters:
args_dictdict

Dictionary containing command-line arguments with ‘data’ and ‘model_path’ keys.

Returns:
tuple of (OrderedDict, array)
  • data_dict: OrderedDict with “measured” key containing structured array of radius and cumulative PSF data

  • radius: Array of radius values in cm

Raises:
FileNotFoundError

If no data file is specified in args_dict.

ray_tracing.psf_parameter_optimisation.run_gradient_descent_optimization(tel_model, site_model, args_dict, data_to_plot, radius, rmsd_threshold, learning_rate, output_dir)[source]#

Run gradient descent optimization to minimize PSF fitting metric.

Parameters:
tel_modelTelescopeModel

Telescope model object to be optimized.

site_modelSiteModel

Site model object with environmental conditions.

args_dictdict

Dictionary containing simulation configuration arguments.

data_to_plotdict

Dictionary containing measured PSF data under “measured” key.

radiusarray-like

Radius values in cm for PSF evaluation.

rmsd_thresholdfloat

Convergence threshold for RMSD improvement.

learning_ratefloat

Initial learning rate for gradient descent steps.

output_dirPath

Directory for saving optimization plots and results.

Returns:
tuple of (dict, float, list)
  • best_params: Dictionary of optimized parameter values

  • best_psf_diameter: PSF containment diameter in cm for the best parameters

  • results: List of (params, metric, p_value, psf_diameter, simulated_data) for each iteration

Returns None values if optimization fails or no measurement data is provided.
ray_tracing.psf_parameter_optimisation.run_psf_optimization_workflow(tel_model, site_model, args_dict, output_dir)[source]#

Run the complete PSF parameter optimization workflow using gradient descent.

ray_tracing.psf_parameter_optimisation.run_psf_simulation(tel_model, site, args_dict, pars, data_to_plot, radius, pdf_pages=None, is_best=False, use_ks_statistic=False)[source]#

Run PSF simulation for given parameters and calculate optimization metric.

Parameters:
tel_modelTelescopeModel

Telescope model object to be configured with the test parameters.

siteSite

Site model object with environmental conditions.

args_dictdict

Dictionary containing simulation configuration arguments.

parsdict

Dictionary of parameter values to test in the simulation.

data_to_plotdict

Dictionary containing measured PSF data under “measured” key.

radiusarray-like

Radius values in cm for PSF evaluation.

pdf_pagesPdfPages, optional

PDF pages object for saving plots (default: None).

is_bestbool, optional

Flag indicating if this is the best parameter set (default: False).

use_ks_statisticbool, optional

If True, use KS statistic as metric; if False, use RMSD (default: False).

Returns:
tuple of (float, float, float or None, array)
  • psf_diameter: PSF containment diameter of the simulated PSF in cm

  • metric: RMSD or KS statistic value

  • p_value: p-value from KS test (None if using RMSD)

  • simulated_data: Structured array with simulated cumulative PSF data

ray_tracing.psf_parameter_optimisation.write_gradient_descent_log(gd_results, best_pars, best_psf_diameter, output_dir, tel_model, use_ks_statistic=False, fraction=0.8)[source]#

Write gradient descent optimization progression to a log file.

Parameters:
gd_resultslist

List of tuples containing (params, metric, p_value, psf_diameter, simulated_data) for each optimization iteration.

best_parsdict

Dictionary containing the best parameter values found.

best_psf_diameterfloat

PSF containment diameter in cm for the best parameter set.

output_dirPath

Directory where the log file will be written.

tel_modelTelescopeModel

Telescope model object for naming the output file.

use_ks_statisticbool, optional

If True, log KS statistic values; if False, log RMSD values (default: False).

fractionfloat, optional

PSF containment fraction for labeling (default: 0.8).

Returns:
Path

Path to the created log file.

ray_tracing.psf_parameter_optimisation.write_monte_carlo_analysis(mc_results, output_dir, tel_model, use_ks_statistic=False, fraction=0.8)[source]#

Write Monte Carlo uncertainty analysis results to a log file.

Parameters:
mc_resultstuple

Tuple of Monte Carlo analysis results from analyze_monte_carlo_error().

output_dirPath

Directory where the log file will be written.

tel_modelTelescopeModel

Telescope model object for naming the output file.

use_ks_statisticbool, optional

If True, analyze KS statistic results; if False, analyze RMSD results (default: False).

fractionfloat, optional

PSF containment fraction for labeling (default: 0.8).

Returns:
Path

Path to the created log file.

ray_tracing.psf_parameter_optimisation.write_tested_parameters_to_file(results, best_pars, best_psf_diameter, output_dir, tel_model, fraction=0.8)[source]#

Write optimization results and tested parameters to a log file.

Parameters:
resultslist

List of tuples containing (parameters, ks_statistic, p_value, psf_diameter, simulated_data) for each tested parameter set.

best_parsdict

Dictionary containing the best parameter values found.

best_psf_diameterfloat

PSF containment diameter in cm for the best parameter set.

output_dirPath

Directory where the log file will be written.

tel_modelTelescopeModel

Telescope model object for naming the output file.

fractionfloat, optional

PSF containment fraction for labeling (default: 0.8).

Returns:
Path

Path to the created log file.

mirror_panel_psf#

Mirror panel PSF calculation.

class ray_tracing.mirror_panel_psf.MirrorPanelPSF(label, args_dict, db_config)[source]#

Mirror panel PSF and random reflection angle calculation.

This class is used to derive the random reflection angle for the mirror panels in the telescope.

Known limitations: single Gaussian PSF model, no support for multiple PSF components (as allowed in the model parameters).

Parameters:
label: str

Application label.

args_dict: dict

Dictionary with input arguments.

db_config:

Dictionary with database configuration.

derive_random_reflection_angle(save_figures=False)[source]#

Minimize the difference between measured and simulated PSF for reflection angle.

Main loop of the optimization process. The method iterates over different values of the random reflection angle until the difference in the mean value of the D80 containment is minimal.

print_results()[source]#

Print results to stdout.

run_simulations_and_analysis(rnda, save_figures=False)[source]#

Run ray tracing simulations and analysis for one given value of rnda.

Parameters:
rnda: float

Random reflection angle in degrees.

save_figures: bool

Save figures.

Returns:
mean_d80: float

Mean value of D80 in cm.

sig_d80: float

Standard deviation of D80 in cm.

write_optimization_data()[source]#

Write optimization results to an astropy table (ecsv file).

Used mostly for debugging of the optimization process. The first entry of the table is the best fit result.