gammasimtools 0.15.0__py3-none-any.whl → 0.16.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/METADATA +2 -32
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/RECORD +222 -214
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/entry_points.txt +5 -2
- simtools/_version.py +2 -2
- simtools/applications/calculate_trigger_rate.py +10 -10
- simtools/applications/convert_all_model_parameters_from_simtel.py +16 -16
- simtools/applications/convert_model_parameter_from_simtel.py +1 -1
- simtools/applications/derive_psf_parameters.py +12 -9
- simtools/applications/docs_produce_array_element_report.py +3 -3
- simtools/applications/docs_produce_calibration_reports.py +49 -0
- simtools/applications/docs_produce_simulation_configuration_report.py +50 -0
- simtools/applications/{generate_simtel_array_histograms.py → generate_sim_telarray_histograms.py} +2 -2
- simtools/applications/production_derive_corsika_limits.py +63 -10
- simtools/applications/production_derive_statistics.py +125 -0
- simtools/applications/production_generate_grid.py +197 -0
- simtools/applications/production_generate_simulation_config.py +0 -10
- simtools/applications/simulate_light_emission.py +5 -13
- simtools/applications/simulate_prod.py +16 -4
- simtools/applications/validate_cumulative_psf.py +6 -4
- simtools/applications/validate_file_using_schema.py +7 -3
- simtools/applications/validate_optics.py +5 -4
- simtools/camera/camera_efficiency.py +14 -39
- simtools/configuration/commandline_parser.py +4 -3
- simtools/configuration/configurator.py +10 -0
- simtools/corsika/corsika_config.py +103 -5
- simtools/data_model/format_checkers.py +9 -0
- simtools/data_model/model_data_writer.py +3 -0
- simtools/data_model/schema.py +27 -16
- simtools/data_model/validate_data.py +27 -7
- simtools/db/db_handler.py +10 -4
- simtools/layout/array_layout.py +1 -0
- simtools/model/array_model.py +63 -29
- simtools/model/model_parameter.py +76 -51
- simtools/model/model_utils.py +43 -1
- simtools/model/site_model.py +3 -2
- simtools/model/telescope_model.py +4 -4
- simtools/production_configuration/calculate_statistical_errors_grid_point.py +0 -4
- simtools/production_configuration/{event_scaler.py → derive_production_statistics.py} +24 -20
- simtools/production_configuration/derive_production_statistics_handler.py +119 -0
- simtools/production_configuration/generate_production_grid.py +364 -0
- simtools/production_configuration/generate_simulation_config.py +9 -9
- simtools/production_configuration/interpolation_handler.py +16 -11
- simtools/ray_tracing/mirror_panel_psf.py +16 -20
- simtools/ray_tracing/psf_analysis.py +2 -2
- simtools/ray_tracing/ray_tracing.py +5 -1
- simtools/reporting/docs_read_parameters.py +361 -58
- simtools/runners/corsika_runner.py +11 -1
- simtools/runners/corsika_simtel_runner.py +80 -89
- simtools/runners/runner_services.py +17 -4
- simtools/runners/simtel_runner.py +27 -10
- simtools/schemas/model_parameter.metaschema.yml +4 -0
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +1 -0
- simtools/schemas/model_parameters/adjust_gain.schema.yml +2 -2
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +2 -2
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +2 -2
- simtools/schemas/model_parameters/array_window.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_shaping.schema.yml +2 -2
- simtools/schemas/model_parameters/asum_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/axes_offsets.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_diameter.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_config_file.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_config_rotate.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_degraded_map.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_depth.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_filter.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_pixels.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_transmission.schema.yml +2 -2
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +2 -2
- simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +2 -2
- simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +90 -1
- simtools/schemas/model_parameters/default_trigger.schema.yml +2 -2
- simtools/schemas/model_parameters/design_model.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/disc_start.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/dish_shape_length.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_pedsub.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_shaping.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +3 -3
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +2 -2
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_max_signal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_mhz.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_noise.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +2 -2
- simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +2 -2
- simtools/schemas/model_parameters/fake_mirror_list.schema.yml +1 -1
- simtools/schemas/model_parameters/flatfielding.schema.yml +2 -2
- simtools/schemas/model_parameters/focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/focus_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/gain_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/hg_lg_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/iobuf_maximum.schema.yml +2 -2
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +2 -2
- simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +2 -2
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +2 -2
- simtools/schemas/model_parameters/min_photons.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_class.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_list.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +2 -2
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +2 -2
- simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +2 -2
- simtools/schemas/model_parameters/num_gains.schema.yml +2 -2
- simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +2 -2
- simtools/schemas/model_parameters/optics_properties.schema.yml +2 -2
- simtools/schemas/model_parameters/pedestal_events.schema.yml +7 -3
- simtools/schemas/model_parameters/photon_delay.schema.yml +2 -2
- simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_average_gain.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_gain_index.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +2 -2
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +2 -2
- simtools/schemas/model_parameters/qe_variation.schema.yml +2 -2
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +2 -2
- simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/random_generator.schema.yml +2 -2
- simtools/schemas/model_parameters/random_mono_probability.schema.yml +2 -2
- simtools/schemas/model_parameters/sampled_output.schema.yml +2 -2
- simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +2 -2
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +2 -2
- simtools/schemas/model_parameters/tailcut_scale.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_axis_height.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_random_angle.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_random_error.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +2 -2
- simtools/schemas/model_parameters/telescope_transmission.schema.yml +2 -2
- simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +2 -2
- simtools/schemas/model_parameters/teltrig_min_time.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_error.schema.yml +2 -2
- simtools/schemas/model_parameters/transit_time_jitter.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_current_limit.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +2 -2
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +2 -2
- simtools/simtel/simtel_config_reader.py +21 -17
- simtools/simtel/simtel_config_writer.py +237 -65
- simtools/simtel/simtel_io_file_info.py +57 -0
- simtools/simtel/simtel_io_histogram.py +10 -14
- simtools/simtel/simtel_io_histograms.py +2 -2
- simtools/simtel/simtel_io_metadata.py +91 -0
- simtools/simtel/simulator_array.py +26 -12
- simtools/simtel/simulator_camera_efficiency.py +12 -6
- simtools/simtel/simulator_light_emission.py +6 -11
- simtools/simtel/simulator_ray_tracing.py +14 -4
- simtools/simulator.py +230 -66
- simtools/testing/configuration.py +5 -0
- simtools/testing/helpers.py +18 -0
- simtools/testing/sim_telarray_metadata.py +212 -0
- simtools/testing/validate_output.py +12 -5
- simtools/utils/general.py +18 -27
- simtools/utils/names.py +27 -5
- simtools/visualization/visualize.py +2 -2
- simtools/applications/production_scale_events.py +0 -185
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.15.0.dist-info → gammasimtools-0.16.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module defines the `GridGeneration` class.
|
|
3
|
+
|
|
4
|
+
Used to generate a grid of simulation points based on flexible axes definitions such
|
|
5
|
+
azimuth, zenith angle, night-sky background, and camera offset.
|
|
6
|
+
The module handles axis binning, scaling and interpolation of energy thresholds, viewcone,
|
|
7
|
+
and radius limits from a lookup table.
|
|
8
|
+
Additionally, it allows for converting between Altitude/Azimuth and Right Ascension
|
|
9
|
+
Declination coordinates. The resulting grid points are saved to a file.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import logging
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
from astropy import units as u
|
|
17
|
+
from astropy.coordinates import AltAz, EarthLocation, SkyCoord
|
|
18
|
+
from astropy.table import Table
|
|
19
|
+
from astropy.units import Quantity
|
|
20
|
+
from scipy.interpolate import griddata
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GridGeneration:
|
|
24
|
+
"""
|
|
25
|
+
Defines and generates a grid of simulation points based on flexible axes definitions.
|
|
26
|
+
|
|
27
|
+
This class generates a grid of points for a simulation based on parameters such as
|
|
28
|
+
azimuth, zenith angle, night-sky background, and camera offset,
|
|
29
|
+
taking into account axis definitions, scaling, and units and interpolating values
|
|
30
|
+
for simulations from a lookup table.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
axes: dict,
|
|
36
|
+
coordinate_system: str = "zenith_azimuth",
|
|
37
|
+
observing_location=None,
|
|
38
|
+
observing_time=None,
|
|
39
|
+
lookup_table: str | None = None,
|
|
40
|
+
telescope_ids: list | None = None,
|
|
41
|
+
):
|
|
42
|
+
"""
|
|
43
|
+
Initialize the grid with the given axes and coordinate system.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
axes : dict
|
|
48
|
+
Dictionary where each key is the axis name and the value is a dictionary
|
|
49
|
+
defining the axis properties (range, binning, scaling, etc.).
|
|
50
|
+
coordinate_system : str, optional
|
|
51
|
+
The coordinate system for the grid generation (default is 'zenith_azimuth').
|
|
52
|
+
observing_location : EarthLocation, optional
|
|
53
|
+
The location of the observation (latitude, longitude, height).
|
|
54
|
+
observing_time : Time, optional
|
|
55
|
+
The time of the observation. If None, coordinate conversion to RA/Dec not working.
|
|
56
|
+
lookup_table : str, optional
|
|
57
|
+
Path to the lookup table file (ECSV format).
|
|
58
|
+
telescope_ids : list of int, optional
|
|
59
|
+
List of telescope IDs to get the limits for.
|
|
60
|
+
"""
|
|
61
|
+
self._logger = logging.getLogger(__name__)
|
|
62
|
+
|
|
63
|
+
self.axes = axes["axes"] if "axes" in axes else axes
|
|
64
|
+
self.coordinate_system = coordinate_system
|
|
65
|
+
self.observing_location = (
|
|
66
|
+
observing_location
|
|
67
|
+
if observing_location is not None
|
|
68
|
+
else EarthLocation(lat=0.0 * u.deg, lon=0.0 * u.deg, height=0 * u.m)
|
|
69
|
+
)
|
|
70
|
+
self.observing_time = observing_time
|
|
71
|
+
self.lookup_table = lookup_table
|
|
72
|
+
self.telescope_ids = telescope_ids
|
|
73
|
+
|
|
74
|
+
# Store target values for each axis
|
|
75
|
+
self.target_values = self._generate_target_values()
|
|
76
|
+
|
|
77
|
+
if self.lookup_table:
|
|
78
|
+
self._apply_lookup_table_limits()
|
|
79
|
+
|
|
80
|
+
def _generate_target_values(self):
|
|
81
|
+
"""
|
|
82
|
+
Generate target axis values and store them as Quantities.
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
dict
|
|
87
|
+
Dictionary of target values for each axis, stored as Quantity objects.
|
|
88
|
+
"""
|
|
89
|
+
target_values = {}
|
|
90
|
+
for axis_name, axis in self.axes.items():
|
|
91
|
+
axis_range = axis["range"]
|
|
92
|
+
binning = axis["binning"]
|
|
93
|
+
scaling = axis.get("scaling", "linear")
|
|
94
|
+
units = axis.get("units", None)
|
|
95
|
+
|
|
96
|
+
if axis_name == "azimuth":
|
|
97
|
+
# Use circular binning for azimuth
|
|
98
|
+
values = self.create_circular_binning(axis_range, binning)
|
|
99
|
+
elif scaling == "log":
|
|
100
|
+
# Log scaling
|
|
101
|
+
values = np.logspace(np.log10(axis_range[0]), np.log10(axis_range[1]), binning)
|
|
102
|
+
elif scaling == "1/cos":
|
|
103
|
+
# 1/cos scaling
|
|
104
|
+
cos_min = np.cos(np.radians(axis_range[0]))
|
|
105
|
+
cos_max = np.cos(np.radians(axis_range[1]))
|
|
106
|
+
inv_cos_values = np.linspace(1 / cos_min, 1 / cos_max, binning)
|
|
107
|
+
values = np.degrees(np.arccos(1 / inv_cos_values))
|
|
108
|
+
else:
|
|
109
|
+
# Linear scaling
|
|
110
|
+
values = np.linspace(axis_range[0], axis_range[1], binning)
|
|
111
|
+
|
|
112
|
+
if units:
|
|
113
|
+
values = values * u.Unit(units)
|
|
114
|
+
|
|
115
|
+
target_values[axis_name] = values
|
|
116
|
+
|
|
117
|
+
return target_values
|
|
118
|
+
|
|
119
|
+
def _apply_lookup_table_limits(self):
|
|
120
|
+
"""Apply limits from the lookup table and interpolate values."""
|
|
121
|
+
lookup_table = Table.read(self.lookup_table, format="ascii.ecsv")
|
|
122
|
+
|
|
123
|
+
matching_rows = [
|
|
124
|
+
row for row in lookup_table if set(self.telescope_ids) == set(row["telescope_ids"])
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
if not matching_rows:
|
|
128
|
+
raise ValueError(
|
|
129
|
+
f"No matching rows in the lookup table for telescope_ids: {self.telescope_ids}"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def extract_array(field, transform=lambda x: x):
|
|
133
|
+
return np.array([transform(row[field]) for row in matching_rows])
|
|
134
|
+
|
|
135
|
+
zeniths = extract_array("zenith")
|
|
136
|
+
azimuths = extract_array("azimuth", lambda x: x % 360)
|
|
137
|
+
nsb_values = extract_array("nsb", lambda x: 1 if x == "dark" else 5)
|
|
138
|
+
lower_energy_thresholds = extract_array("lower_energy_threshold")
|
|
139
|
+
upper_radius_thresholds = extract_array("upper_radius_threshold")
|
|
140
|
+
viewcone_radii = extract_array("viewcone_radius")
|
|
141
|
+
|
|
142
|
+
# Wrap azimuths and repeat others
|
|
143
|
+
azimuths_wrapped = np.concatenate([azimuths + shift for shift in (0, 360, -360)])
|
|
144
|
+
|
|
145
|
+
def repeat_3(arr):
|
|
146
|
+
"""Repeat an array three times."""
|
|
147
|
+
return np.tile(arr, 3)
|
|
148
|
+
|
|
149
|
+
points = np.column_stack(
|
|
150
|
+
(
|
|
151
|
+
repeat_3(zeniths),
|
|
152
|
+
azimuths_wrapped,
|
|
153
|
+
repeat_3(nsb_values),
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
target_grid = (
|
|
158
|
+
np.array(
|
|
159
|
+
np.meshgrid(
|
|
160
|
+
self.target_values["zenith_angle"].value,
|
|
161
|
+
self.target_values["azimuth"].value,
|
|
162
|
+
self.target_values["nsb"].value,
|
|
163
|
+
indexing="ij",
|
|
164
|
+
)
|
|
165
|
+
)
|
|
166
|
+
.reshape(3, -1)
|
|
167
|
+
.T
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
def interpolate(values):
|
|
171
|
+
return griddata(
|
|
172
|
+
points, repeat_3(values), target_grid, method="linear", fill_value=np.nan
|
|
173
|
+
).reshape(
|
|
174
|
+
len(self.target_values["zenith_angle"]),
|
|
175
|
+
len(self.target_values["azimuth"]),
|
|
176
|
+
len(self.target_values["nsb"]),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
self.interpolated_limits = {
|
|
180
|
+
"energy": interpolate(lower_energy_thresholds),
|
|
181
|
+
"radius": interpolate(upper_radius_thresholds),
|
|
182
|
+
"viewcone": interpolate(viewcone_radii),
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
def create_circular_binning(self, azimuth_range, num_bins):
|
|
186
|
+
"""
|
|
187
|
+
Create bin centers for azimuth angles, handling circular wraparound (0 deg to 360 deg).
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
azimuth_range : tuple
|
|
192
|
+
(min_azimuth, max_azimuth), can wrap around 0 deg.
|
|
193
|
+
num_bins : int
|
|
194
|
+
Number of bins.
|
|
195
|
+
|
|
196
|
+
Returns
|
|
197
|
+
-------
|
|
198
|
+
np.ndarray
|
|
199
|
+
Array of bin centers.
|
|
200
|
+
"""
|
|
201
|
+
azimuth_min, azimuth_max = azimuth_range
|
|
202
|
+
azimuth_min %= 360 # Normalize to [0, 360)
|
|
203
|
+
azimuth_max %= 360
|
|
204
|
+
|
|
205
|
+
clockwise_distance = (azimuth_max - azimuth_min) % 360
|
|
206
|
+
counterclockwise_distance = (azimuth_min - azimuth_max) % 360
|
|
207
|
+
|
|
208
|
+
if clockwise_distance <= counterclockwise_distance:
|
|
209
|
+
bin_centers = (
|
|
210
|
+
np.linspace(azimuth_min, azimuth_min + clockwise_distance, num_bins, endpoint=True)
|
|
211
|
+
% 360
|
|
212
|
+
)
|
|
213
|
+
else:
|
|
214
|
+
bin_centers = (
|
|
215
|
+
np.linspace(
|
|
216
|
+
azimuth_min, azimuth_min - counterclockwise_distance, num_bins, endpoint=True
|
|
217
|
+
)
|
|
218
|
+
% 360
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
return bin_centers
|
|
222
|
+
|
|
223
|
+
def generate_grid(self) -> list[dict]:
|
|
224
|
+
"""
|
|
225
|
+
Generate the grid based on the required axes and include interpolated limits.
|
|
226
|
+
|
|
227
|
+
Takes energy threshold, viewcone, and radius from the interpolated lookup table.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
list of dict
|
|
232
|
+
A list of grid points, each represented as a dictionary with axis names
|
|
233
|
+
as keys and axis values as values. Axis values may include units where defined.
|
|
234
|
+
"""
|
|
235
|
+
value_arrays = [value.value for value in self.target_values.values()]
|
|
236
|
+
units = [value.unit for value in self.target_values.values()]
|
|
237
|
+
grid = np.meshgrid(*value_arrays, indexing="ij")
|
|
238
|
+
combinations = np.vstack(list(map(np.ravel, grid))).T
|
|
239
|
+
grid_points = []
|
|
240
|
+
for combination in combinations:
|
|
241
|
+
grid_point = {
|
|
242
|
+
key: Quantity(combination[i], units[i])
|
|
243
|
+
for i, key in enumerate(self.target_values.keys())
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if "energy" in self.interpolated_limits:
|
|
247
|
+
zenith_idx = np.searchsorted(
|
|
248
|
+
self.target_values["zenith_angle"].value, grid_point["zenith_angle"].value
|
|
249
|
+
)
|
|
250
|
+
azimuth_idx = np.searchsorted(
|
|
251
|
+
self.target_values["azimuth"].value, grid_point["azimuth"].value
|
|
252
|
+
)
|
|
253
|
+
nsb_idx = np.searchsorted(self.target_values["nsb"].value, grid_point["nsb"].value)
|
|
254
|
+
energy_lower = self.interpolated_limits["energy"][zenith_idx, azimuth_idx, nsb_idx]
|
|
255
|
+
grid_point["energy_threshold"] = {"lower": energy_lower * u.TeV}
|
|
256
|
+
|
|
257
|
+
if "radius" in self.interpolated_limits:
|
|
258
|
+
radius_value = self.interpolated_limits["radius"][zenith_idx, azimuth_idx, nsb_idx]
|
|
259
|
+
grid_point["radius"] = radius_value * u.m
|
|
260
|
+
|
|
261
|
+
if "viewcone" in self.interpolated_limits:
|
|
262
|
+
viewcone_value = self.interpolated_limits["viewcone"][
|
|
263
|
+
zenith_idx, azimuth_idx, nsb_idx
|
|
264
|
+
]
|
|
265
|
+
grid_point["viewcone"] = viewcone_value * u.deg
|
|
266
|
+
|
|
267
|
+
grid_points.append(grid_point)
|
|
268
|
+
|
|
269
|
+
return grid_points
|
|
270
|
+
|
|
271
|
+
def convert_altaz_to_radec(self, alt, az):
|
|
272
|
+
"""
|
|
273
|
+
Convert Altitude/Azimuth (AltAz) coordinates to Right Ascension/Declination (RA/Dec).
|
|
274
|
+
|
|
275
|
+
Parameters
|
|
276
|
+
----------
|
|
277
|
+
alt : float
|
|
278
|
+
Altitude angle in degrees.
|
|
279
|
+
az : float
|
|
280
|
+
Azimuth angle in degrees.
|
|
281
|
+
|
|
282
|
+
Returns
|
|
283
|
+
-------
|
|
284
|
+
SkyCoord
|
|
285
|
+
SkyCoord object containing the RA/Dec coordinates.
|
|
286
|
+
|
|
287
|
+
Raises
|
|
288
|
+
------
|
|
289
|
+
ValueError
|
|
290
|
+
If observing_time is not set.
|
|
291
|
+
"""
|
|
292
|
+
if self.observing_time is None:
|
|
293
|
+
raise ValueError(
|
|
294
|
+
"Observing time is not set. "
|
|
295
|
+
"Please provide an observing_time to convert coordinates."
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
alt_rad = alt.to(u.rad)
|
|
299
|
+
az_rad = az.to(u.rad)
|
|
300
|
+
aa = AltAz(
|
|
301
|
+
alt=alt_rad,
|
|
302
|
+
az=az_rad,
|
|
303
|
+
location=self.observing_location,
|
|
304
|
+
obstime=self.observing_time,
|
|
305
|
+
)
|
|
306
|
+
skycoord = SkyCoord(aa)
|
|
307
|
+
return skycoord.icrs # Return RA/Dec in ICRS frame
|
|
308
|
+
|
|
309
|
+
def convert_coordinates(self, grid_points: list[dict]) -> list[dict]:
|
|
310
|
+
"""
|
|
311
|
+
Convert the grid points to RA/Dec coordinates if necessary.
|
|
312
|
+
|
|
313
|
+
Parameters
|
|
314
|
+
----------
|
|
315
|
+
grid_points : list of dict
|
|
316
|
+
List of grid points, each represented as a dictionary with axis
|
|
317
|
+
names as keys and values.
|
|
318
|
+
|
|
319
|
+
Returns
|
|
320
|
+
-------
|
|
321
|
+
list of dict
|
|
322
|
+
The grid points with converted RA/Dec coordinates.
|
|
323
|
+
"""
|
|
324
|
+
if self.coordinate_system == "ra_dec":
|
|
325
|
+
for point in grid_points:
|
|
326
|
+
if "zenith_angle" in point and "azimuth" in point:
|
|
327
|
+
alt = (90.0 * u.deg) - point.pop("zenith_angle")
|
|
328
|
+
az = point.pop("azimuth")
|
|
329
|
+
radec = self.convert_altaz_to_radec(alt, az)
|
|
330
|
+
point["ra"] = radec.ra.deg * u.deg
|
|
331
|
+
point["dec"] = radec.dec.deg * u.deg
|
|
332
|
+
return grid_points
|
|
333
|
+
|
|
334
|
+
def serialize_grid_points(self, grid_points, output_file=None):
|
|
335
|
+
"""Serialize the grid output and save to a file or print to the console."""
|
|
336
|
+
cleaned_points = []
|
|
337
|
+
|
|
338
|
+
for point in grid_points:
|
|
339
|
+
cleaned_point = {}
|
|
340
|
+
for key, value in point.items():
|
|
341
|
+
if isinstance(value, dict):
|
|
342
|
+
# Nested dictionaries
|
|
343
|
+
cleaned_point[key] = {k: self.serialize_quantity(v) for k, v in value.items()}
|
|
344
|
+
else:
|
|
345
|
+
cleaned_point[key] = self.serialize_quantity(value)
|
|
346
|
+
|
|
347
|
+
cleaned_points.append(cleaned_point)
|
|
348
|
+
|
|
349
|
+
output_data = json.dumps(cleaned_points, indent=4)
|
|
350
|
+
|
|
351
|
+
if output_file:
|
|
352
|
+
with open(output_file, "w", encoding="utf-8") as f:
|
|
353
|
+
f.write(output_data)
|
|
354
|
+
self._logger.info(f"Output saved to {output_file}")
|
|
355
|
+
else:
|
|
356
|
+
self._logger.info(output_data)
|
|
357
|
+
return output_data
|
|
358
|
+
|
|
359
|
+
def serialize_quantity(self, value):
|
|
360
|
+
"""Serialize Quantity."""
|
|
361
|
+
if isinstance(value, u.Quantity):
|
|
362
|
+
return {"value": value.value, "unit": str(value.unit)}
|
|
363
|
+
self._logger.warning(f"Unsupported type {type(value)} for serialization. Returning as is.")
|
|
364
|
+
return value
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
from simtools.production_configuration.calculate_statistical_errors_grid_point import (
|
|
4
4
|
StatisticalErrorEvaluator,
|
|
5
5
|
)
|
|
6
|
-
from simtools.production_configuration.
|
|
6
|
+
from simtools.production_configuration.derive_production_statistics import (
|
|
7
|
+
ProductionStatisticsDerivator,
|
|
8
|
+
)
|
|
7
9
|
|
|
8
10
|
__all__ = ["SimulationConfig"]
|
|
9
11
|
|
|
@@ -18,8 +20,6 @@ class SimulationConfig:
|
|
|
18
20
|
Dictionary representing a grid point with azimuth, elevation, and night sky background.
|
|
19
21
|
file_path : str
|
|
20
22
|
Path to the DL2 MC event file for statistical uncertainty evaluation.
|
|
21
|
-
file_type : str
|
|
22
|
-
Type of the DL2 MC event file ('point-like' or 'cone').
|
|
23
23
|
metrics : dict, optional
|
|
24
24
|
Dictionary of metrics to evaluate.
|
|
25
25
|
"""
|
|
@@ -28,16 +28,16 @@ class SimulationConfig:
|
|
|
28
28
|
self,
|
|
29
29
|
grid_point: dict[str, float],
|
|
30
30
|
file_path: str,
|
|
31
|
-
file_type: str,
|
|
32
31
|
metrics: dict[str, float] | None = None,
|
|
33
32
|
):
|
|
34
33
|
"""Initialize the simulation configuration for a grid point."""
|
|
35
34
|
self.grid_point = grid_point
|
|
36
35
|
self.file_path = file_path
|
|
37
|
-
self.file_type = file_type
|
|
38
36
|
self.metrics = metrics or {}
|
|
39
|
-
self.evaluator = StatisticalErrorEvaluator(file_path,
|
|
40
|
-
self.
|
|
37
|
+
self.evaluator = StatisticalErrorEvaluator(file_path, metrics)
|
|
38
|
+
self.derive_production_statistics = ProductionStatisticsDerivator(
|
|
39
|
+
self.evaluator, self.metrics
|
|
40
|
+
)
|
|
41
41
|
self.simulation_params = {}
|
|
42
42
|
|
|
43
43
|
def configure_simulation(self) -> dict[str, float]:
|
|
@@ -61,14 +61,14 @@ class SimulationConfig:
|
|
|
61
61
|
"""
|
|
62
62
|
Calculate the required number of simulated events based on statistical error metrics.
|
|
63
63
|
|
|
64
|
-
Uses the
|
|
64
|
+
Uses the ProductionStatisticsDerivator to scale the events.
|
|
65
65
|
|
|
66
66
|
Returns
|
|
67
67
|
-------
|
|
68
68
|
int
|
|
69
69
|
The number of simulated events required.
|
|
70
70
|
"""
|
|
71
|
-
return self.
|
|
71
|
+
return self.derive_production_statistics.derive_statistics()
|
|
72
72
|
|
|
73
73
|
def _calculate_core_scatter_area(self) -> float:
|
|
74
74
|
"""
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Handle interpolation between multiple StatisticalErrorEvaluator instances."""
|
|
2
2
|
|
|
3
3
|
import astropy.units as u
|
|
4
4
|
import numpy as np
|
|
5
5
|
from scipy.interpolate import griddata
|
|
6
6
|
|
|
7
|
-
from simtools.production_configuration.
|
|
7
|
+
from simtools.production_configuration.derive_production_statistics import (
|
|
8
|
+
ProductionStatisticsDerivator,
|
|
9
|
+
)
|
|
8
10
|
|
|
9
11
|
__all__ = ["InterpolationHandler"]
|
|
10
12
|
|
|
@@ -15,7 +17,9 @@ class InterpolationHandler:
|
|
|
15
17
|
def __init__(self, evaluators, metrics: dict):
|
|
16
18
|
self.evaluators = evaluators
|
|
17
19
|
self.metrics = metrics
|
|
18
|
-
self.
|
|
20
|
+
self.derive_production_statistics = [
|
|
21
|
+
ProductionStatisticsDerivator(e, self.metrics) for e in self.evaluators
|
|
22
|
+
]
|
|
19
23
|
|
|
20
24
|
self.azimuths = [e.grid_point[1].to(u.deg).value for e in self.evaluators]
|
|
21
25
|
self.zeniths = [e.grid_point[2].to(u.deg).value for e in self.evaluators]
|
|
@@ -26,8 +30,9 @@ class InterpolationHandler:
|
|
|
26
30
|
(e.data["bin_edges_low"][:-1] + e.data["bin_edges_high"][:-1]) / 2
|
|
27
31
|
for e in self.evaluators
|
|
28
32
|
]
|
|
29
|
-
self.
|
|
30
|
-
|
|
33
|
+
self.production_statistics = [
|
|
34
|
+
derivator.derive_statistics(return_sum=False)
|
|
35
|
+
for derivator in self.derive_production_statistics
|
|
31
36
|
]
|
|
32
37
|
self.energy_thresholds = np.array([e.energy_threshold for e in self.evaluators])
|
|
33
38
|
|
|
@@ -48,8 +53,8 @@ class InterpolationHandler:
|
|
|
48
53
|
flat_data_list = []
|
|
49
54
|
flat_grid_points = []
|
|
50
55
|
|
|
51
|
-
for e, energy_grid,
|
|
52
|
-
self.evaluators, self.energy_grids, self.
|
|
56
|
+
for e, energy_grid, production_statistics in zip(
|
|
57
|
+
self.evaluators, self.energy_grids, self.production_statistics
|
|
53
58
|
):
|
|
54
59
|
az = np.full(len(energy_grid), e.grid_point[1].to(u.deg).value)
|
|
55
60
|
zen = np.full(len(energy_grid), e.grid_point[2].to(u.deg).value)
|
|
@@ -59,7 +64,7 @@ class InterpolationHandler:
|
|
|
59
64
|
# Combine grid points and data
|
|
60
65
|
grid_points = np.column_stack([energy_grid.to(u.TeV).value, az, zen, nsb, offset])
|
|
61
66
|
flat_grid_points.append(grid_points)
|
|
62
|
-
flat_data_list.append(
|
|
67
|
+
flat_data_list.append(production_statistics)
|
|
63
68
|
|
|
64
69
|
# Flatten the list and convert to numpy arrays
|
|
65
70
|
flat_grid_points = np.vstack(flat_grid_points)
|
|
@@ -153,7 +158,7 @@ class InterpolationHandler:
|
|
|
153
158
|
|
|
154
159
|
def plot_comparison(self, evaluator):
|
|
155
160
|
"""
|
|
156
|
-
Plot a comparison between the simulated,
|
|
161
|
+
Plot a comparison between the simulated, derived, and reconstructed events.
|
|
157
162
|
|
|
158
163
|
Parameters
|
|
159
164
|
----------
|
|
@@ -176,7 +181,7 @@ class InterpolationHandler:
|
|
|
176
181
|
|
|
177
182
|
self.interpolate(self.grid_points)
|
|
178
183
|
|
|
179
|
-
plt.plot(midpoints, evaluator.
|
|
184
|
+
plt.plot(midpoints, evaluator.production_statistics, label="Derived")
|
|
180
185
|
|
|
181
186
|
reconstructed_event_histogram, _ = np.histogram(
|
|
182
187
|
evaluator.data["event_energies_reco"], bins=evaluator.data["bin_edges_low"]
|
|
@@ -187,5 +192,5 @@ class InterpolationHandler:
|
|
|
187
192
|
plt.xscale("log")
|
|
188
193
|
plt.xlabel("Energy (Midpoint of Bin Edges)")
|
|
189
194
|
plt.ylabel("Event Count")
|
|
190
|
-
plt.title("Comparison of
|
|
195
|
+
plt.title("Comparison of simulated, derived, and reconstructed events")
|
|
191
196
|
plt.show()
|
|
@@ -9,7 +9,7 @@ from astropy.table import QTable, Table
|
|
|
9
9
|
import simtools.data_model.model_data_writer as writer
|
|
10
10
|
import simtools.utils.general as gen
|
|
11
11
|
from simtools.data_model.metadata_collector import MetadataCollector
|
|
12
|
-
from simtools.model.
|
|
12
|
+
from simtools.model.model_utils import initialize_simulation_models
|
|
13
13
|
from simtools.ray_tracing.ray_tracing import RayTracing
|
|
14
14
|
|
|
15
15
|
|
|
@@ -38,7 +38,7 @@ class MirrorPanelPSF:
|
|
|
38
38
|
self._logger.debug("Initializing MirrorPanelPSF")
|
|
39
39
|
|
|
40
40
|
self.args_dict = args_dict
|
|
41
|
-
self.telescope_model = self._define_telescope_model(label, db_config)
|
|
41
|
+
self.telescope_model, self.site_model = self._define_telescope_model(label, db_config)
|
|
42
42
|
|
|
43
43
|
if self.args_dict["test"]:
|
|
44
44
|
self.args_dict["number_of_mirrors_to_test"] = 2
|
|
@@ -63,37 +63,32 @@ class MirrorPanelPSF:
|
|
|
63
63
|
This includes updating the configuration with mirror list and/or random focal length given
|
|
64
64
|
as input.
|
|
65
65
|
|
|
66
|
-
Attributes
|
|
67
|
-
----------
|
|
68
|
-
label: str
|
|
69
|
-
Application label.
|
|
70
|
-
db_config:
|
|
71
|
-
Dictionary with database configuration.
|
|
72
|
-
|
|
73
66
|
Returns
|
|
74
67
|
-------
|
|
75
|
-
tel TelescopeModel
|
|
76
|
-
telescope model
|
|
77
|
-
|
|
68
|
+
tel : TelescopeModel
|
|
69
|
+
The telescope model.
|
|
70
|
+
site_model : SiteModel
|
|
71
|
+
The site model.
|
|
78
72
|
"""
|
|
79
|
-
|
|
73
|
+
tel_model, site_model = initialize_simulation_models(
|
|
74
|
+
label=label,
|
|
75
|
+
db_config=db_config,
|
|
80
76
|
site=self.args_dict["site"],
|
|
81
77
|
telescope_name=self.args_dict["telescope"],
|
|
82
78
|
model_version=self.args_dict["model_version"],
|
|
83
|
-
mongo_db_config=db_config,
|
|
84
|
-
label=label,
|
|
85
79
|
)
|
|
86
80
|
if self.args_dict["mirror_list"] is not None:
|
|
87
81
|
mirror_list_file = gen.find_file(
|
|
88
82
|
name=self.args_dict["mirror_list"], loc=self.args_dict["model_path"]
|
|
89
83
|
)
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
tel_model.change_parameter("mirror_list", self.args_dict["mirror_list"])
|
|
85
|
+
tel_model.export_parameter_file("mirror_list", mirror_list_file)
|
|
92
86
|
if self.args_dict["random_focal_length"] is not None:
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
tel_model.change_parameter(
|
|
88
|
+
"random_focal_length", str(self.args_dict["random_focal_length"])
|
|
89
|
+
)
|
|
95
90
|
|
|
96
|
-
return
|
|
91
|
+
return tel_model, site_model
|
|
97
92
|
|
|
98
93
|
def _get_psf_containment(self):
|
|
99
94
|
"""Read measured single-mirror point-spread function from file and return mean and sigma."""
|
|
@@ -229,6 +224,7 @@ class MirrorPanelPSF:
|
|
|
229
224
|
self.telescope_model.change_parameter("mirror_reflection_random_angle", rnda)
|
|
230
225
|
ray = RayTracing(
|
|
231
226
|
telescope_model=self.telescope_model,
|
|
227
|
+
site_model=self.site_model,
|
|
232
228
|
simtel_path=self.args_dict.get("simtel_path", None),
|
|
233
229
|
single_mirror_mode=True,
|
|
234
230
|
mirror_numbers=(
|
|
@@ -91,7 +91,7 @@ class PSFImage:
|
|
|
91
91
|
|
|
92
92
|
def _process_simtel_file_using_rx(self, photon_file):
|
|
93
93
|
"""
|
|
94
|
-
Process a
|
|
94
|
+
Process a sim_telarray file with photon lists using the RX method.
|
|
95
95
|
|
|
96
96
|
Parameters
|
|
97
97
|
----------
|
|
@@ -152,7 +152,7 @@ class PSFImage:
|
|
|
152
152
|
self._process_simtel_line(line)
|
|
153
153
|
|
|
154
154
|
if not self._is_photon_positions_ok():
|
|
155
|
-
msg = "Problems reading
|
|
155
|
+
msg = "Problems reading sim_telarray file - invalid data"
|
|
156
156
|
self._logger.error(msg)
|
|
157
157
|
raise RuntimeError(msg)
|
|
158
158
|
|
|
@@ -33,6 +33,8 @@ class RayTracing:
|
|
|
33
33
|
----------
|
|
34
34
|
telescope_model: TelescopeModel
|
|
35
35
|
telescope model
|
|
36
|
+
site_model: SiteModel
|
|
37
|
+
site model
|
|
36
38
|
simtel_path: str (or Path)
|
|
37
39
|
Location of sim_telarray installation.
|
|
38
40
|
label: str
|
|
@@ -61,6 +63,7 @@ class RayTracing:
|
|
|
61
63
|
def __init__(
|
|
62
64
|
self,
|
|
63
65
|
telescope_model,
|
|
66
|
+
site_model,
|
|
64
67
|
simtel_path,
|
|
65
68
|
label=None,
|
|
66
69
|
zenith_angle=20.0 * u.deg,
|
|
@@ -77,7 +80,7 @@ class RayTracing:
|
|
|
77
80
|
self.simtel_path = Path(simtel_path)
|
|
78
81
|
self._io_handler = io_handler.IOHandler()
|
|
79
82
|
|
|
80
|
-
self.telescope_model = telescope_model
|
|
83
|
+
self.telescope_model, self.site_model = telescope_model, site_model
|
|
81
84
|
self.label = label if label is not None else self.telescope_model.label
|
|
82
85
|
|
|
83
86
|
self.zenith_angle = zenith_angle.to("deg").value
|
|
@@ -211,6 +214,7 @@ class RayTracing:
|
|
|
211
214
|
simtel = SimulatorRayTracing(
|
|
212
215
|
simtel_path=self.simtel_path,
|
|
213
216
|
telescope_model=self.telescope_model,
|
|
217
|
+
site_model=self.site_model,
|
|
214
218
|
test=test,
|
|
215
219
|
config_data={
|
|
216
220
|
"zenith_angle": self.zenith_angle,
|