gammasimtools 0.25.0__py3-none-any.whl → 0.26.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.25.0.dist-info → gammasimtools-0.26.0.dist-info}/METADATA +2 -1
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/RECORD +122 -121
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/entry_points.txt +2 -1
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/licenses/LICENSE +1 -1
- simtools/_version.py +2 -2
- simtools/application_control.py +35 -7
- simtools/applications/calculate_incident_angles.py +0 -2
- simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -2
- simtools/applications/db_add_file_to_db.py +1 -1
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +1 -1
- simtools/applications/db_add_value_from_json_to_db.py +1 -1
- simtools/applications/db_generate_compound_indexes.py +1 -1
- simtools/applications/db_get_array_layouts_from_db.py +2 -6
- simtools/applications/db_get_file_from_db.py +1 -1
- simtools/applications/db_get_parameter_from_db.py +1 -1
- simtools/applications/db_inspect_databases.py +1 -1
- simtools/applications/db_upload_model_repository.py +1 -1
- simtools/applications/derive_ctao_array_layouts.py +1 -2
- simtools/applications/derive_mirror_rnda.py +1 -3
- simtools/applications/derive_psf_parameters.py +0 -1
- simtools/applications/derive_pulse_shape_parameters.py +0 -1
- simtools/applications/derive_trigger_rates.py +1 -1
- simtools/applications/docs_produce_array_element_report.py +2 -8
- simtools/applications/docs_produce_calibration_reports.py +1 -3
- simtools/applications/docs_produce_model_parameter_reports.py +0 -2
- simtools/applications/docs_produce_simulation_configuration_report.py +1 -3
- simtools/applications/generate_array_config.py +0 -1
- simtools/applications/generate_corsika_histograms.py +48 -235
- simtools/applications/generate_regular_arrays.py +5 -35
- simtools/applications/generate_simtel_event_data.py +2 -2
- simtools/applications/maintain_simulation_model_add_production.py +2 -2
- simtools/applications/maintain_simulation_model_write_array_element_positions.py +87 -0
- simtools/applications/plot_array_layout.py +5 -111
- simtools/applications/plot_simulated_event_distributions.py +57 -0
- simtools/applications/plot_tabular_data.py +0 -1
- simtools/applications/plot_tabular_data_for_model_parameter.py +1 -6
- simtools/applications/production_derive_corsika_limits.py +1 -1
- simtools/applications/production_generate_grid.py +0 -1
- simtools/applications/run_application.py +1 -1
- simtools/applications/simulate_flasher.py +0 -2
- simtools/applications/simulate_illuminator.py +0 -1
- simtools/applications/simulate_pedestals.py +1 -5
- simtools/applications/simulate_prod.py +1 -5
- simtools/applications/simulate_prod_htcondor_generator.py +1 -1
- simtools/applications/submit_array_layouts.py +2 -4
- simtools/applications/submit_model_parameter_from_external.py +1 -3
- simtools/applications/validate_camera_efficiency.py +0 -1
- simtools/applications/validate_camera_fov.py +0 -1
- simtools/applications/validate_cumulative_psf.py +0 -2
- simtools/applications/validate_optics.py +0 -13
- simtools/camera/camera_efficiency.py +1 -6
- simtools/camera/single_photon_electron_spectrum.py +2 -1
- simtools/configuration/commandline_parser.py +35 -2
- simtools/configuration/configurator.py +6 -11
- simtools/corsika/corsika_config.py +16 -21
- simtools/corsika/corsika_histograms.py +411 -1735
- simtools/corsika/primary_particle.py +1 -1
- simtools/data_model/metadata_collector.py +5 -2
- simtools/data_model/metadata_model.py +0 -4
- simtools/data_model/model_data_writer.py +13 -15
- simtools/data_model/validate_data.py +1 -3
- simtools/db/db_handler.py +19 -8
- simtools/dependencies.py +81 -38
- simtools/io/ascii_handler.py +4 -2
- simtools/io/table_handler.py +1 -1
- simtools/layout/array_layout.py +4 -12
- simtools/layout/array_layout_utils.py +226 -57
- simtools/model/array_model.py +1 -13
- simtools/model/calibration_model.py +0 -4
- simtools/model/legacy_model_parameter.py +134 -0
- simtools/model/model_parameter.py +24 -13
- simtools/model/model_utils.py +1 -6
- simtools/model/site_model.py +0 -4
- simtools/model/telescope_model.py +6 -11
- simtools/production_configuration/derive_corsika_limits.py +6 -11
- simtools/production_configuration/interpolation_handler.py +16 -16
- simtools/ray_tracing/incident_angles.py +5 -11
- simtools/ray_tracing/mirror_panel_psf.py +3 -7
- simtools/ray_tracing/psf_analysis.py +18 -19
- simtools/ray_tracing/psf_parameter_optimisation.py +0 -1
- simtools/ray_tracing/ray_tracing.py +6 -15
- simtools/reporting/docs_auto_report_generator.py +8 -13
- simtools/reporting/docs_read_parameters.py +2 -8
- simtools/runners/corsika_runner.py +5 -9
- simtools/runners/corsika_simtel_runner.py +3 -8
- simtools/runners/simtel_runner.py +0 -5
- simtools/runners/simtools_runner.py +2 -4
- simtools/settings.py +154 -0
- simtools/{io/eventio_handler.py → sim_events/file_info.py} +3 -3
- simtools/{simtel/simtel_io_event_histograms.py → sim_events/histograms.py} +25 -15
- simtools/{simtel/simtel_io_event_reader.py → sim_events/reader.py} +20 -17
- simtools/{simtel/simtel_io_event_writer.py → sim_events/writer.py} +84 -25
- simtools/simtel/pulse_shapes.py +7 -2
- simtools/simtel/simtel_config_writer.py +79 -36
- simtools/simtel/simtel_table_reader.py +6 -4
- simtools/simtel/simulator_array.py +4 -11
- simtools/simtel/simulator_camera_efficiency.py +4 -6
- simtools/simtel/simulator_light_emission.py +69 -24
- simtools/simtel/simulator_ray_tracing.py +4 -10
- simtools/simulator.py +7 -14
- simtools/telescope_trigger_rates.py +3 -4
- simtools/testing/assertions.py +84 -33
- simtools/testing/configuration.py +1 -2
- simtools/testing/helpers.py +2 -3
- simtools/testing/log_inspector.py +1 -0
- simtools/testing/sim_telarray_metadata.py +1 -1
- simtools/testing/validate_output.py +34 -23
- simtools/utils/general.py +37 -0
- simtools/utils/geometry.py +0 -77
- simtools/utils/names.py +5 -5
- simtools/visualization/legend_handlers.py +7 -6
- simtools/visualization/plot_array_layout.py +91 -16
- simtools/visualization/plot_corsika_histograms.py +143 -605
- simtools/visualization/plot_mirrors.py +1 -4
- simtools/visualization/plot_pixels.py +2 -4
- simtools/visualization/plot_psf.py +0 -1
- simtools/visualization/plot_simtel_event_histograms.py +4 -4
- simtools/visualization/plot_simtel_events.py +6 -11
- simtools/visualization/plot_tables.py +8 -19
- simtools/visualization/visualize.py +22 -2
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +0 -160
- simtools/applications/print_version.py +0 -53
- simtools/io/hdf5_handler.py +0 -139
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/top_level.txt +0 -0
|
@@ -11,6 +11,7 @@ import simtools.utils.general as gen
|
|
|
11
11
|
from simtools.data_model import schema
|
|
12
12
|
from simtools.db import db_handler
|
|
13
13
|
from simtools.io import ascii_handler, io_handler
|
|
14
|
+
from simtools.model import legacy_model_parameter
|
|
14
15
|
from simtools.simtel.simtel_config_writer import SimtelConfigWriter
|
|
15
16
|
from simtools.utils import names, value_conversion
|
|
16
17
|
|
|
@@ -28,8 +29,6 @@ class ModelParameter:
|
|
|
28
29
|
|
|
29
30
|
Parameters
|
|
30
31
|
----------
|
|
31
|
-
db_config:
|
|
32
|
-
Database configuration dictionary.
|
|
33
32
|
model_version: str
|
|
34
33
|
Version of the model (ex. 5.0.0).
|
|
35
34
|
site: str
|
|
@@ -51,7 +50,6 @@ class ModelParameter:
|
|
|
51
50
|
|
|
52
51
|
def __init__(
|
|
53
52
|
self,
|
|
54
|
-
db_config,
|
|
55
53
|
model_version,
|
|
56
54
|
site=None,
|
|
57
55
|
array_element_name=None,
|
|
@@ -62,7 +60,9 @@ class ModelParameter:
|
|
|
62
60
|
):
|
|
63
61
|
self._logger = logging.getLogger(__name__)
|
|
64
62
|
self.io_handler = io_handler.IOHandler()
|
|
65
|
-
self.db = db_handler.DatabaseHandler(
|
|
63
|
+
self.db = db_handler.DatabaseHandler()
|
|
64
|
+
if not self.db.is_configured():
|
|
65
|
+
raise RuntimeError("Database is not configured.")
|
|
66
66
|
|
|
67
67
|
self.parameters = {}
|
|
68
68
|
self._simulation_config_parameters = {sw: {} for sw in names.simulation_software()}
|
|
@@ -327,35 +327,46 @@ class ModelParameter:
|
|
|
327
327
|
)
|
|
328
328
|
if self.overwrite_model_parameters:
|
|
329
329
|
self.overwrite_parameters_from_file(self.overwrite_model_parameters)
|
|
330
|
-
self.
|
|
330
|
+
self._check_model_parameter_versions(self.parameters)
|
|
331
331
|
|
|
332
332
|
self._load_simulation_software_parameter()
|
|
333
333
|
for software_name, parameters in self._simulation_config_parameters.items():
|
|
334
|
-
self.
|
|
335
|
-
parameters.keys(), software_name=software_name
|
|
336
|
-
)
|
|
334
|
+
self._check_model_parameter_versions(parameters, software_name=software_name)
|
|
337
335
|
|
|
338
|
-
def
|
|
336
|
+
def _check_model_parameter_versions(self, parameters, software_name=None):
|
|
339
337
|
"""
|
|
340
|
-
Ensure
|
|
338
|
+
Ensure parameters follow the latest schema and are compatible with installed software.
|
|
341
339
|
|
|
342
340
|
Compares software versions listed in schema files with the installed software versions
|
|
343
341
|
(e.g., sim_telarray, CORSIKA).
|
|
344
342
|
|
|
343
|
+
For outdated model parameter schemas, legacy update functions are called to update
|
|
344
|
+
the parameters to the latest schema version.
|
|
345
|
+
|
|
345
346
|
Parameters
|
|
346
347
|
----------
|
|
347
|
-
|
|
348
|
-
|
|
348
|
+
parameters: dict
|
|
349
|
+
Dictionary containing model parameters.
|
|
349
350
|
software_name: str
|
|
350
351
|
Name of the software for which the parameters are checked.
|
|
351
352
|
"""
|
|
352
|
-
|
|
353
|
+
_legacy_updates = {}
|
|
354
|
+
for par_name, par_data in parameters.items():
|
|
353
355
|
if par_name in (parameter_schema := names.model_parameters()):
|
|
354
356
|
schema.validate_deprecation_and_version(
|
|
355
357
|
data=parameter_schema[par_name],
|
|
356
358
|
software_name=software_name,
|
|
357
359
|
ignore_software_version=self.ignore_software_version,
|
|
358
360
|
)
|
|
361
|
+
_latest_schema_version = parameter_schema[par_name]["schema_version"]
|
|
362
|
+
if par_data["model_parameter_schema_version"] != _latest_schema_version:
|
|
363
|
+
_legacy_updates.update(
|
|
364
|
+
legacy_model_parameter.update_parameter(
|
|
365
|
+
par_name, parameters, _latest_schema_version
|
|
366
|
+
)
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
legacy_model_parameter.apply_legacy_updates_to_parameters(parameters, _legacy_updates)
|
|
359
370
|
|
|
360
371
|
def overwrite_model_parameter(self, par_name, value, parameter_version=None):
|
|
361
372
|
"""
|
simtools/model/model_utils.py
CHANGED
|
@@ -10,7 +10,7 @@ from simtools.utils import names
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def initialize_simulation_models(
|
|
13
|
-
label,
|
|
13
|
+
label, model_version, site, telescope_name, calibration_device_name=None
|
|
14
14
|
):
|
|
15
15
|
"""
|
|
16
16
|
Initialize simulation models for a single telescope, site, and calibration device model.
|
|
@@ -19,8 +19,6 @@ def initialize_simulation_models(
|
|
|
19
19
|
----------
|
|
20
20
|
label: str
|
|
21
21
|
Label for the simulation.
|
|
22
|
-
db_config: dict
|
|
23
|
-
Database configuration.
|
|
24
22
|
model_version: str
|
|
25
23
|
Version of the simulation model
|
|
26
24
|
site: str
|
|
@@ -38,21 +36,18 @@ def initialize_simulation_models(
|
|
|
38
36
|
tel_model = TelescopeModel(
|
|
39
37
|
site=site,
|
|
40
38
|
telescope_name=telescope_name,
|
|
41
|
-
db_config=db_config,
|
|
42
39
|
model_version=model_version,
|
|
43
40
|
label=label,
|
|
44
41
|
)
|
|
45
42
|
site_model = SiteModel(
|
|
46
43
|
site=site,
|
|
47
44
|
model_version=model_version,
|
|
48
|
-
db_config=db_config,
|
|
49
45
|
label=label,
|
|
50
46
|
)
|
|
51
47
|
if calibration_device_name is not None:
|
|
52
48
|
calibration_model = CalibrationModel(
|
|
53
49
|
site=site,
|
|
54
50
|
calibration_device_model_name=calibration_device_name,
|
|
55
|
-
db_config=db_config,
|
|
56
51
|
model_version=model_version,
|
|
57
52
|
label=label,
|
|
58
53
|
)
|
simtools/model/site_model.py
CHANGED
|
@@ -26,8 +26,6 @@ class SiteModel(ModelParameter):
|
|
|
26
26
|
----------
|
|
27
27
|
site: str
|
|
28
28
|
Site name (e.g., South or North).
|
|
29
|
-
db_config: dict
|
|
30
|
-
Database configuration.
|
|
31
29
|
model_version: str or list
|
|
32
30
|
Model version or list of model versions (in which case only the first one is used).
|
|
33
31
|
label: str, optional
|
|
@@ -41,7 +39,6 @@ class SiteModel(ModelParameter):
|
|
|
41
39
|
def __init__(
|
|
42
40
|
self,
|
|
43
41
|
site,
|
|
44
|
-
db_config,
|
|
45
42
|
model_version,
|
|
46
43
|
label=None,
|
|
47
44
|
overwrite_model_parameters=None,
|
|
@@ -52,7 +49,6 @@ class SiteModel(ModelParameter):
|
|
|
52
49
|
self._logger.debug("Init SiteModel for site %s", site)
|
|
53
50
|
super().__init__(
|
|
54
51
|
site=site,
|
|
55
|
-
db_config=db_config,
|
|
56
52
|
model_version=model_version,
|
|
57
53
|
label=label,
|
|
58
54
|
collection="sites",
|
|
@@ -26,8 +26,6 @@ class TelescopeModel(ModelParameter):
|
|
|
26
26
|
Site name (e.g., South or North).
|
|
27
27
|
telescope_name: str
|
|
28
28
|
Telescope name (ex. LSTN-01, LSTN-design, ...).
|
|
29
|
-
db_config: dict
|
|
30
|
-
Database configuration.
|
|
31
29
|
model_version: str
|
|
32
30
|
Model version.
|
|
33
31
|
label: str, optional
|
|
@@ -42,7 +40,6 @@ class TelescopeModel(ModelParameter):
|
|
|
42
40
|
self,
|
|
43
41
|
site,
|
|
44
42
|
telescope_name,
|
|
45
|
-
db_config,
|
|
46
43
|
model_version,
|
|
47
44
|
label=None,
|
|
48
45
|
overwrite_model_parameters=None,
|
|
@@ -52,7 +49,6 @@ class TelescopeModel(ModelParameter):
|
|
|
52
49
|
super().__init__(
|
|
53
50
|
site=site,
|
|
54
51
|
array_element_name=telescope_name,
|
|
55
|
-
db_config=db_config,
|
|
56
52
|
model_version=model_version,
|
|
57
53
|
label=label,
|
|
58
54
|
overwrite_model_parameters=overwrite_model_parameters,
|
|
@@ -326,13 +322,12 @@ class TelescopeModel(ModelParameter):
|
|
|
326
322
|
average_curve: astropy.table.Table
|
|
327
323
|
Instance of astropy.table.Table with the averaged curve.
|
|
328
324
|
"""
|
|
329
|
-
weights = [
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
)
|
|
325
|
+
weights = [
|
|
326
|
+
incidence_angle_dist["Fraction"][
|
|
327
|
+
np.nanargmin(np.abs(angle_now - incidence_angle_dist["Incidence angle"].value))
|
|
328
|
+
]
|
|
329
|
+
for angle_now in curves["Angle"]
|
|
330
|
+
]
|
|
336
331
|
|
|
337
332
|
return Table(
|
|
338
333
|
[curves["Wavelength"], np.average(curves["z"], weights=weights, axis=0)],
|
|
@@ -10,13 +10,13 @@ from astropy.table import Column, Table
|
|
|
10
10
|
from simtools.data_model.metadata_collector import MetadataCollector
|
|
11
11
|
from simtools.io import ascii_handler, io_handler
|
|
12
12
|
from simtools.layout.array_layout_utils import get_array_elements_from_db_for_layouts
|
|
13
|
-
from simtools.
|
|
13
|
+
from simtools.sim_events.histograms import EventDataHistograms
|
|
14
14
|
from simtools.visualization import plot_simtel_event_histograms
|
|
15
15
|
|
|
16
16
|
_logger = logging.getLogger(__name__)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def generate_corsika_limits_grid(args_dict
|
|
19
|
+
def generate_corsika_limits_grid(args_dict):
|
|
20
20
|
"""
|
|
21
21
|
Generate CORSIKA limits.
|
|
22
22
|
|
|
@@ -24,15 +24,12 @@ def generate_corsika_limits_grid(args_dict, db_config=None):
|
|
|
24
24
|
----------
|
|
25
25
|
args_dict : dict
|
|
26
26
|
Dictionary containing command line arguments.
|
|
27
|
-
db_config : dict, optional
|
|
28
|
-
Database configuration dictionary.
|
|
29
27
|
"""
|
|
30
28
|
if args_dict.get("array_layout_name"):
|
|
31
29
|
telescope_configs = get_array_elements_from_db_for_layouts(
|
|
32
30
|
args_dict["array_layout_name"],
|
|
33
31
|
args_dict.get("site"),
|
|
34
32
|
args_dict.get("model_version"),
|
|
35
|
-
db_config,
|
|
36
33
|
)
|
|
37
34
|
else:
|
|
38
35
|
telescope_configs = ascii_handler.collect_data_from_file(args_dict["telescope_ids"])[
|
|
@@ -81,9 +78,7 @@ def _process_file(file_path, array_name, telescope_ids, loss_fraction, plot_hist
|
|
|
81
78
|
dict
|
|
82
79
|
Dictionary containing the computed limits and metadata.
|
|
83
80
|
"""
|
|
84
|
-
histograms =
|
|
85
|
-
file_path, array_name=array_name, telescope_list=telescope_ids
|
|
86
|
-
)
|
|
81
|
+
histograms = EventDataHistograms(file_path, array_name=array_name, telescope_list=telescope_ids)
|
|
87
82
|
histograms.fill()
|
|
88
83
|
|
|
89
84
|
limits = {
|
|
@@ -257,7 +252,7 @@ def compute_lower_energy_limit(histograms, loss_fraction):
|
|
|
257
252
|
|
|
258
253
|
Parameters
|
|
259
254
|
----------
|
|
260
|
-
histograms :
|
|
255
|
+
histograms : EventDataHistograms
|
|
261
256
|
Histograms.
|
|
262
257
|
loss_fraction : float
|
|
263
258
|
Fraction of events to be lost.
|
|
@@ -299,7 +294,7 @@ def compute_upper_radius_limit(histograms, loss_fraction):
|
|
|
299
294
|
|
|
300
295
|
Parameters
|
|
301
296
|
----------
|
|
302
|
-
histograms :
|
|
297
|
+
histograms : EventDataHistograms
|
|
303
298
|
Histograms.
|
|
304
299
|
loss_fraction : float
|
|
305
300
|
Fraction of events to be lost.
|
|
@@ -337,7 +332,7 @@ def compute_viewcone(histograms, loss_fraction):
|
|
|
337
332
|
|
|
338
333
|
Parameters
|
|
339
334
|
----------
|
|
340
|
-
histograms :
|
|
335
|
+
histograms : EventDataHistograms
|
|
341
336
|
Histograms.
|
|
342
337
|
loss_fraction : float
|
|
343
338
|
Fraction of events to be lost.
|
|
@@ -214,17 +214,15 @@ class InterpolationHandler:
|
|
|
214
214
|
np.ndarray
|
|
215
215
|
Reduced production grid points.
|
|
216
216
|
"""
|
|
217
|
-
production_grid_points = [
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
[
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
]
|
|
227
|
-
)
|
|
217
|
+
production_grid_points = [
|
|
218
|
+
[
|
|
219
|
+
point["azimuth"]["value"],
|
|
220
|
+
point["zenith_angle"]["value"],
|
|
221
|
+
point["nsb"]["value"],
|
|
222
|
+
point["offset"]["value"],
|
|
223
|
+
]
|
|
224
|
+
for point in self.grid_points_production
|
|
225
|
+
]
|
|
228
226
|
|
|
229
227
|
production_grid_points = np.array(production_grid_points)
|
|
230
228
|
|
|
@@ -280,11 +278,13 @@ class InterpolationHandler:
|
|
|
280
278
|
reduced_production_grid_points = self._prepare_production_grid_points()
|
|
281
279
|
energy_grid = self.energy_grids[0] if self.energy_grids else []
|
|
282
280
|
|
|
283
|
-
energy_query_grid = [
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
281
|
+
energy_query_grid = [
|
|
282
|
+
[
|
|
283
|
+
np.hstack([energy.to(u.TeV).value, grid_point])
|
|
284
|
+
for energy in energy_grid
|
|
285
|
+
for grid_point in reduced_production_grid_points
|
|
286
|
+
]
|
|
287
|
+
]
|
|
288
288
|
energy_query_grid = np.array(energy_query_grid)
|
|
289
289
|
|
|
290
290
|
self._logger.debug(f"Grid points with energy shape: {grid_points_energy.shape}")
|
|
@@ -15,6 +15,7 @@ from pathlib import Path
|
|
|
15
15
|
import astropy.units as u
|
|
16
16
|
from astropy.table import QTable
|
|
17
17
|
|
|
18
|
+
from simtools import settings
|
|
18
19
|
from simtools.data_model.metadata_collector import MetadataCollector
|
|
19
20
|
from simtools.model.model_utils import initialize_simulation_models
|
|
20
21
|
|
|
@@ -24,10 +25,6 @@ class IncidentAnglesCalculator:
|
|
|
24
25
|
|
|
25
26
|
Parameters
|
|
26
27
|
----------
|
|
27
|
-
simtel_path : str or pathlib.Path
|
|
28
|
-
Path to the sim_telarray installation directory (containing ``sim_telarray/bin``).
|
|
29
|
-
db_config : dict
|
|
30
|
-
Database configuration passed to ``initialize_simulation_models``.
|
|
31
28
|
config_data : dict
|
|
32
29
|
Simulation configuration (e.g. ``site``, ``telescope``, ``model_version``,
|
|
33
30
|
``off_axis_angle``, ``source_distance``, ``number_of_photons``).
|
|
@@ -48,15 +45,12 @@ class IncidentAnglesCalculator:
|
|
|
48
45
|
|
|
49
46
|
def __init__(
|
|
50
47
|
self,
|
|
51
|
-
simtel_path,
|
|
52
|
-
db_config,
|
|
53
48
|
config_data,
|
|
54
49
|
output_dir,
|
|
55
50
|
label=None,
|
|
56
51
|
):
|
|
57
52
|
self.logger = logging.getLogger(__name__)
|
|
58
53
|
|
|
59
|
-
self._simtel_path = Path(simtel_path)
|
|
60
54
|
self.config_data = config_data
|
|
61
55
|
self.output_dir = Path(output_dir)
|
|
62
56
|
self.label = label or f"incident_angles_{config_data['telescope']}"
|
|
@@ -82,7 +76,6 @@ class IncidentAnglesCalculator:
|
|
|
82
76
|
)
|
|
83
77
|
self.telescope_model, self.site_model, _ = initialize_simulation_models(
|
|
84
78
|
label=self.label,
|
|
85
|
-
db_config=db_config,
|
|
86
79
|
site=config_data["site"],
|
|
87
80
|
telescope_name=config_data["telescope"],
|
|
88
81
|
model_version=config_data["model_version"],
|
|
@@ -216,8 +209,6 @@ class IncidentAnglesCalculator:
|
|
|
216
209
|
Path to the generated shell script.
|
|
217
210
|
"""
|
|
218
211
|
script_path = self.scripts_dir / f"run_incident_angles_{self._label_suffix()}.sh"
|
|
219
|
-
simtel_bin = self._simtel_path / "sim_telarray/bin/sim_telarray_debug_trace"
|
|
220
|
-
corsika_dummy = self._simtel_path / "sim_telarray/run9991.corsika.gz"
|
|
221
212
|
|
|
222
213
|
theta = self.ZENITH_ANGLE_DEG
|
|
223
214
|
off = float(self.config_data["off_axis_angle"].to_value(u.deg))
|
|
@@ -258,7 +249,10 @@ class IncidentAnglesCalculator:
|
|
|
258
249
|
cfg("camera_filter", "none"),
|
|
259
250
|
]
|
|
260
251
|
|
|
261
|
-
command =
|
|
252
|
+
command = (
|
|
253
|
+
f"{settings.config.sim_telarray_exe_debug_trace} {' '.join(opts)} "
|
|
254
|
+
f"{settings.config.corsika_dummy_file}"
|
|
255
|
+
)
|
|
262
256
|
with script_path.open("w", encoding="utf-8") as sh:
|
|
263
257
|
sh.write("#!/usr/bin/env bash\n\n")
|
|
264
258
|
sh.write("set -e\nset -o pipefail\n\n")
|
|
@@ -28,17 +28,15 @@ class MirrorPanelPSF:
|
|
|
28
28
|
Application label.
|
|
29
29
|
args_dict: dict
|
|
30
30
|
Dictionary with input arguments.
|
|
31
|
-
db_config:
|
|
32
|
-
Dictionary with database configuration.
|
|
33
31
|
"""
|
|
34
32
|
|
|
35
|
-
def __init__(self, label, args_dict
|
|
33
|
+
def __init__(self, label, args_dict):
|
|
36
34
|
"""Initialize the MirrorPanelPSF class."""
|
|
37
35
|
self._logger = logging.getLogger(__name__)
|
|
38
36
|
self._logger.debug("Initializing MirrorPanelPSF")
|
|
39
37
|
|
|
40
38
|
self.args_dict = args_dict
|
|
41
|
-
self.telescope_model, self.site_model = self._define_telescope_model(label
|
|
39
|
+
self.telescope_model, self.site_model = self._define_telescope_model(label)
|
|
42
40
|
|
|
43
41
|
if self.args_dict["test"]:
|
|
44
42
|
self.args_dict["number_of_mirrors_to_test"] = 2
|
|
@@ -56,7 +54,7 @@ class MirrorPanelPSF:
|
|
|
56
54
|
self.results_mean = []
|
|
57
55
|
self.results_sig = []
|
|
58
56
|
|
|
59
|
-
def _define_telescope_model(self, label
|
|
57
|
+
def _define_telescope_model(self, label):
|
|
60
58
|
"""
|
|
61
59
|
Define telescope model.
|
|
62
60
|
|
|
@@ -72,7 +70,6 @@ class MirrorPanelPSF:
|
|
|
72
70
|
"""
|
|
73
71
|
tel_model, site_model, _ = initialize_simulation_models(
|
|
74
72
|
label=label,
|
|
75
|
-
db_config=db_config,
|
|
76
73
|
site=self.args_dict["site"],
|
|
77
74
|
telescope_name=self.args_dict["telescope"],
|
|
78
75
|
model_version=self.args_dict["model_version"],
|
|
@@ -225,7 +222,6 @@ class MirrorPanelPSF:
|
|
|
225
222
|
ray = RayTracing(
|
|
226
223
|
telescope_model=self.telescope_model,
|
|
227
224
|
site_model=self.site_model,
|
|
228
|
-
simtel_path=self.args_dict.get("simtel_path", None),
|
|
229
225
|
single_mirror_mode=True,
|
|
230
226
|
mirror_numbers=(
|
|
231
227
|
list(range(1, self.args_dict["number_of_mirrors_to_test"] + 1))
|
|
@@ -17,6 +17,7 @@ import astropy.units as u
|
|
|
17
17
|
import matplotlib.pyplot as plt
|
|
18
18
|
import numpy as np
|
|
19
19
|
|
|
20
|
+
from simtools import settings
|
|
20
21
|
from simtools.utils.general import collect_kwargs, set_default_kwargs
|
|
21
22
|
|
|
22
23
|
|
|
@@ -36,8 +37,6 @@ class PSFImage:
|
|
|
36
37
|
Scatter area of all photons in cm^2. If not given, effective area cannot be computed.
|
|
37
38
|
containment_fraction: float
|
|
38
39
|
Containment fraction for PSF calculation.
|
|
39
|
-
simtel_path: str
|
|
40
|
-
Path to sim_telarray installation.
|
|
41
40
|
"""
|
|
42
41
|
|
|
43
42
|
__PSF_RADIUS = "Radius [cm]"
|
|
@@ -48,11 +47,9 @@ class PSFImage:
|
|
|
48
47
|
focal_length=None,
|
|
49
48
|
total_scattered_area=None,
|
|
50
49
|
containment_fraction=None,
|
|
51
|
-
simtel_path=None,
|
|
52
50
|
):
|
|
53
51
|
"""Initialize PSFImage class."""
|
|
54
52
|
self._logger = logging.getLogger(__name__)
|
|
55
|
-
self.simtel_path = simtel_path
|
|
56
53
|
|
|
57
54
|
self._total_photons = None
|
|
58
55
|
self._number_of_detected_photons = None
|
|
@@ -97,20 +94,23 @@ class PSFImage:
|
|
|
97
94
|
Name of sim_telarray file with photon list.
|
|
98
95
|
"""
|
|
99
96
|
try:
|
|
100
|
-
|
|
97
|
+
with subprocess.Popen(
|
|
101
98
|
shlex.split(
|
|
102
|
-
f"{
|
|
99
|
+
f"{settings.config.sim_telarray_path}/bin/rx "
|
|
100
|
+
f"-f {self._containment_fraction:.2f} -v"
|
|
103
101
|
),
|
|
104
102
|
stdin=subprocess.PIPE,
|
|
105
103
|
stdout=subprocess.PIPE,
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
104
|
+
) as rx_process:
|
|
105
|
+
with gzip.open(photon_file, "rb") as _stdin:
|
|
106
|
+
with rx_process.stdin:
|
|
107
|
+
shutil.copyfileobj(_stdin, rx_process.stdin)
|
|
108
|
+
try:
|
|
109
|
+
rx_output = rx_process.communicate()[0].splitlines()[-1:][0].split()
|
|
110
|
+
except IndexError as e:
|
|
111
|
+
raise IndexError(
|
|
112
|
+
f"Unexpected output format from rx: {rx_process}"
|
|
113
|
+
) from e
|
|
114
114
|
except FileNotFoundError as e:
|
|
115
115
|
raise FileNotFoundError(f"Photon list file not found: {photon_file}") from e
|
|
116
116
|
|
|
@@ -384,7 +384,6 @@ class PSFImage:
|
|
|
384
384
|
if radius is not found (found_radius is False)
|
|
385
385
|
"""
|
|
386
386
|
r0, r1 = rad_min, rad_min + dr
|
|
387
|
-
s0, s1 = 0, 0
|
|
388
387
|
found_radius = False
|
|
389
388
|
while not found_radius:
|
|
390
389
|
s0, s1 = self._sum_photons_in_radius(r0), self._sum_photons_in_radius(r1)
|
|
@@ -497,10 +496,10 @@ class PSFImage:
|
|
|
497
496
|
radius_all = radius.to(u.cm).value if isinstance(radius, u.Quantity) else radius
|
|
498
497
|
else:
|
|
499
498
|
radius_all = list(np.linspace(0, 1.6 * self.get_psf(0.8), 30))
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
499
|
+
intensity = [
|
|
500
|
+
self._sum_photons_in_radius(rad) / self._number_of_detected_photons
|
|
501
|
+
for rad in radius_all
|
|
502
|
+
]
|
|
504
503
|
d_type = {
|
|
505
504
|
"names": (self.__PSF_RADIUS, self.__PSF_CUMULATIVE),
|
|
506
505
|
"formats": ("f8", "f8"),
|
|
@@ -861,7 +861,6 @@ def _run_ray_tracing_simulation(tel_model, site_model, args_dict, pars):
|
|
|
861
861
|
ray = RayTracing(
|
|
862
862
|
telescope_model=tel_model,
|
|
863
863
|
site_model=site_model,
|
|
864
|
-
simtel_path=args_dict["simtel_path"],
|
|
865
864
|
zenith_angle=args_dict["zenith"] * u.deg,
|
|
866
865
|
source_distance=args_dict["src_distance"] * u.km,
|
|
867
866
|
off_axis_angle=[0.0] * u.deg,
|
|
@@ -5,7 +5,6 @@ import logging
|
|
|
5
5
|
import shutil
|
|
6
6
|
from copy import copy
|
|
7
7
|
from math import pi, tan
|
|
8
|
-
from pathlib import Path
|
|
9
8
|
|
|
10
9
|
import astropy.io.ascii
|
|
11
10
|
import astropy.units as u
|
|
@@ -33,8 +32,6 @@ class RayTracing:
|
|
|
33
32
|
telescope model
|
|
34
33
|
site_model: SiteModel
|
|
35
34
|
site model
|
|
36
|
-
simtel_path: str (or Path)
|
|
37
|
-
Location of sim_telarray installation.
|
|
38
35
|
label: str
|
|
39
36
|
label used for output file naming.
|
|
40
37
|
zenith_angle: astropy.units.Quantity
|
|
@@ -64,7 +61,6 @@ class RayTracing:
|
|
|
64
61
|
self,
|
|
65
62
|
telescope_model,
|
|
66
63
|
site_model,
|
|
67
|
-
simtel_path,
|
|
68
64
|
label=None,
|
|
69
65
|
zenith_angle=20.0 * u.deg,
|
|
70
66
|
off_axis_angle=[0.0] * u.deg,
|
|
@@ -78,7 +74,6 @@ class RayTracing:
|
|
|
78
74
|
self._logger = logging.getLogger(__name__)
|
|
79
75
|
self._logger.debug(f"Initializing RayTracing class {single_mirror_mode}")
|
|
80
76
|
|
|
81
|
-
self.simtel_path = Path(simtel_path)
|
|
82
77
|
self._io_handler = io_handler.IOHandler()
|
|
83
78
|
|
|
84
79
|
self.telescope_model, self.site_model = telescope_model, site_model
|
|
@@ -212,7 +207,6 @@ class RayTracing:
|
|
|
212
207
|
f"Simulating RayTracing for off_axis={this_off_axis}, mirror={mirror_number}"
|
|
213
208
|
)
|
|
214
209
|
simtel = SimulatorRayTracing(
|
|
215
|
-
simtel_path=self.simtel_path,
|
|
216
210
|
telescope_model=self.telescope_model,
|
|
217
211
|
site_model=self.site_model,
|
|
218
212
|
test=test,
|
|
@@ -408,11 +402,7 @@ class RayTracing:
|
|
|
408
402
|
PSFImage
|
|
409
403
|
PSF image object.
|
|
410
404
|
"""
|
|
411
|
-
image = PSFImage(
|
|
412
|
-
focal_length=focal_length,
|
|
413
|
-
containment_fraction=containment_fraction,
|
|
414
|
-
simtel_path=self.simtel_path,
|
|
415
|
-
)
|
|
405
|
+
image = PSFImage(focal_length=focal_length, containment_fraction=containment_fraction)
|
|
416
406
|
image.process_photon_list(photons_file, use_rx)
|
|
417
407
|
self._psf_images[this_off_axis] = copy(image)
|
|
418
408
|
return image
|
|
@@ -623,10 +613,11 @@ class RayTracing:
|
|
|
623
613
|
-------
|
|
624
614
|
List of PSFImages
|
|
625
615
|
"""
|
|
626
|
-
images = [
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
616
|
+
images = [
|
|
617
|
+
self._psf_images[this_off_axis]
|
|
618
|
+
for this_off_axis in self.off_axis_angle
|
|
619
|
+
if self._psf_images and this_off_axis in self._psf_images
|
|
620
|
+
]
|
|
630
621
|
if len(images) == 0:
|
|
631
622
|
self._logger.warning("No image found")
|
|
632
623
|
return None
|
|
@@ -16,11 +16,10 @@ logger = logging.getLogger()
|
|
|
16
16
|
class ReportGenerator:
|
|
17
17
|
"""Automate report generation."""
|
|
18
18
|
|
|
19
|
-
def __init__(self,
|
|
19
|
+
def __init__(self, args, output_path):
|
|
20
20
|
"""Initialise class."""
|
|
21
21
|
self._logger = logging.getLogger(__name__)
|
|
22
|
-
self.db = db_handler.DatabaseHandler(
|
|
23
|
-
self.db_config = db_config
|
|
22
|
+
self.db = db_handler.DatabaseHandler()
|
|
24
23
|
self.args = args
|
|
25
24
|
self.output_path = output_path
|
|
26
25
|
|
|
@@ -99,7 +98,7 @@ class ReportGenerator:
|
|
|
99
98
|
)
|
|
100
99
|
|
|
101
100
|
output_path = Path(self.output_path) / str(model_version)
|
|
102
|
-
ReadParameters(self.
|
|
101
|
+
ReadParameters(self.args, output_path).produce_array_element_report()
|
|
103
102
|
|
|
104
103
|
logger.info(
|
|
105
104
|
f"Markdown report generated for {site} "
|
|
@@ -167,9 +166,7 @@ class ReportGenerator:
|
|
|
167
166
|
}
|
|
168
167
|
)
|
|
169
168
|
|
|
170
|
-
ReadParameters(
|
|
171
|
-
self.db_config, self.args, self.output_path
|
|
172
|
-
).produce_model_parameter_reports()
|
|
169
|
+
ReadParameters(self.args, self.output_path).produce_model_parameter_reports()
|
|
173
170
|
|
|
174
171
|
logger.info(
|
|
175
172
|
f"Markdown report generated for {site} Telescope {telescope}: {self.output_path}"
|
|
@@ -211,7 +208,7 @@ class ReportGenerator:
|
|
|
211
208
|
)
|
|
212
209
|
|
|
213
210
|
output_path = Path(self.output_path) / str(model_version)
|
|
214
|
-
ReadParameters(self.
|
|
211
|
+
ReadParameters(self.args, output_path).produce_observatory_report()
|
|
215
212
|
|
|
216
213
|
logger.info(f"Observatory report generated for {site} (v{model_version}): {output_path}")
|
|
217
214
|
|
|
@@ -237,9 +234,7 @@ class ReportGenerator:
|
|
|
237
234
|
self.args.update({"model_version": version})
|
|
238
235
|
output_path = Path(self.output_path) / str(version)
|
|
239
236
|
|
|
240
|
-
ReadParameters(
|
|
241
|
-
self.db_config, self.args, output_path
|
|
242
|
-
).produce_simulation_configuration_report()
|
|
237
|
+
ReadParameters(self.args, output_path).produce_simulation_configuration_report()
|
|
243
238
|
|
|
244
239
|
logger.info(f"Configuration reports for (v{version}) produced: {output_path}")
|
|
245
240
|
|
|
@@ -262,7 +257,7 @@ class ReportGenerator:
|
|
|
262
257
|
output_path = Path(self.output_path) / str(version)
|
|
263
258
|
|
|
264
259
|
try:
|
|
265
|
-
ReadParameters(self.
|
|
260
|
+
ReadParameters(self.args, output_path).produce_calibration_reports()
|
|
266
261
|
logger.info(f"Calibration reports for (v{version}) produced: {output_path}")
|
|
267
262
|
except ValueError as err:
|
|
268
263
|
# Some model versions do not have calibration_devices in the DB;
|
|
@@ -305,7 +300,7 @@ class ReportGenerator:
|
|
|
305
300
|
|
|
306
301
|
# Generate parameter comparison reports for calibration devices
|
|
307
302
|
ReadParameters(
|
|
308
|
-
|
|
303
|
+
version_args, self.output_path
|
|
309
304
|
).generate_model_parameter_reports_for_devices(array_elements)
|
|
310
305
|
|
|
311
306
|
logger.info(
|