gammasimtools 0.22.0__py3-none-any.whl → 0.23.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.22.0.dist-info → gammasimtools-0.23.0.dist-info}/METADATA +2 -1
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/RECORD +114 -112
- simtools/_version.py +2 -2
- simtools/application_control.py +118 -0
- simtools/applications/calculate_incident_angles.py +17 -22
- simtools/applications/convert_all_model_parameters_from_simtel.py +28 -43
- simtools/applications/convert_geo_coordinates_of_array_elements.py +26 -45
- simtools/applications/convert_model_parameter_from_simtel.py +21 -41
- simtools/applications/db_add_file_to_db.py +12 -13
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +20 -33
- simtools/applications/db_add_value_from_json_to_db.py +28 -23
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +19 -34
- simtools/applications/db_generate_compound_indexes.py +11 -13
- simtools/applications/db_get_array_layouts_from_db.py +19 -39
- simtools/applications/db_get_file_from_db.py +15 -17
- simtools/applications/db_get_parameter_from_db.py +33 -35
- simtools/applications/db_inspect_databases.py +10 -11
- simtools/applications/db_upload_model_repository.py +13 -31
- simtools/applications/derive_ctao_array_layouts.py +16 -21
- simtools/applications/derive_mirror_rnda.py +9 -14
- simtools/applications/derive_photon_electron_spectrum.py +7 -10
- simtools/applications/derive_psf_parameters.py +13 -20
- simtools/applications/derive_trigger_rates.py +6 -9
- simtools/applications/docs_produce_array_element_report.py +22 -23
- simtools/applications/docs_produce_calibration_reports.py +26 -24
- simtools/applications/docs_produce_model_parameter_reports.py +15 -22
- simtools/applications/docs_produce_simulation_configuration_report.py +21 -22
- simtools/applications/generate_array_config.py +14 -33
- simtools/applications/generate_corsika_histograms.py +22 -43
- simtools/applications/generate_default_metadata.py +15 -36
- simtools/applications/generate_regular_arrays.py +11 -15
- simtools/applications/generate_simtel_event_data.py +23 -33
- simtools/applications/maintain_simulation_model_add_production.py +12 -19
- simtools/applications/maintain_simulation_model_compare_productions.py +10 -12
- simtools/applications/maintain_simulation_model_verify_production_tables.py +8 -11
- simtools/applications/merge_tables.py +14 -23
- simtools/applications/plot_array_layout.py +77 -54
- simtools/applications/plot_simtel_events.py +11 -13
- simtools/applications/plot_tabular_data.py +17 -38
- simtools/applications/plot_tabular_data_for_model_parameter.py +16 -23
- simtools/applications/print_version.py +14 -42
- simtools/applications/production_derive_corsika_limits.py +5 -9
- simtools/applications/production_derive_statistics.py +12 -25
- simtools/applications/production_generate_grid.py +20 -48
- simtools/applications/production_merge_corsika_limits.py +17 -21
- simtools/applications/run_application.py +12 -32
- simtools/applications/simulate_flasher.py +21 -25
- simtools/applications/simulate_illuminator.py +7 -14
- simtools/applications/simulate_pedestals.py +13 -13
- simtools/applications/simulate_prod.py +21 -33
- simtools/applications/simulate_prod_htcondor_generator.py +11 -25
- simtools/applications/submit_array_layouts.py +15 -18
- simtools/applications/submit_data_from_external.py +18 -34
- simtools/applications/submit_model_parameter_from_external.py +27 -40
- simtools/applications/validate_camera_efficiency.py +23 -21
- simtools/applications/validate_camera_fov.py +21 -26
- simtools/applications/validate_cumulative_psf.py +27 -35
- simtools/applications/validate_file_using_schema.py +15 -33
- simtools/applications/validate_optics.py +26 -32
- simtools/camera/camera_efficiency.py +0 -2
- simtools/configuration/commandline_parser.py +32 -4
- simtools/configuration/configurator.py +0 -5
- simtools/corsika/corsika_config.py +0 -5
- simtools/data_model/data_reader.py +0 -2
- simtools/data_model/metadata_collector.py +0 -2
- simtools/data_model/model_data_writer.py +0 -2
- simtools/data_model/validate_data.py +0 -2
- simtools/db/db_handler.py +0 -2
- simtools/io/hdf5_handler.py +0 -5
- simtools/io/legacy_data_handler.py +0 -5
- simtools/job_execution/job_manager.py +0 -3
- simtools/layout/array_layout.py +0 -2
- simtools/layout/telescope_position.py +0 -2
- simtools/model/array_model.py +2 -4
- simtools/model/calibration_model.py +0 -2
- simtools/model/camera.py +0 -2
- simtools/model/mirrors.py +0 -2
- simtools/model/model_parameter.py +30 -7
- simtools/model/model_utils.py +0 -5
- simtools/model/site_model.py +0 -2
- simtools/model/telescope_model.py +0 -2
- simtools/production_configuration/calculate_statistical_uncertainties_grid_point.py +0 -2
- simtools/production_configuration/derive_production_statistics.py +0 -2
- simtools/production_configuration/interpolation_handler.py +0 -2
- simtools/ray_tracing/psf_analysis.py +0 -2
- simtools/ray_tracing/ray_tracing.py +0 -2
- simtools/reporting/docs_auto_report_generator.py +108 -0
- simtools/reporting/docs_read_parameters.py +1 -7
- simtools/runners/corsika_runner.py +0 -2
- simtools/runners/corsika_simtel_runner.py +0 -2
- simtools/runners/simtel_runner.py +0 -2
- simtools/schemas/model_parameters/transit_time_random.schema.yml +29 -0
- simtools/simtel/simtel_config_reader.py +0 -2
- simtools/simtel/simtel_config_writer.py +31 -13
- simtools/simtel/simtel_io_metadata.py +3 -3
- simtools/simtel/simulator_array.py +9 -21
- simtools/simtel/simulator_camera_efficiency.py +0 -2
- simtools/simtel/simulator_light_emission.py +1 -3
- simtools/simtel/simulator_ray_tracing.py +0 -2
- simtools/simulator.py +0 -5
- simtools/testing/assertions.py +2 -2
- simtools/testing/configuration.py +17 -4
- simtools/utils/general.py +5 -13
- simtools/utils/geometry.py +0 -5
- simtools/utils/names.py +1 -13
- simtools/version.py +61 -0
- simtools/visualization/plot_array_layout.py +129 -23
- simtools/visualization/plot_incident_angles.py +0 -2
- simtools/visualization/plot_simtel_events.py +0 -11
- simtools/visualization/visualize.py +0 -12
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/WHEEL +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/entry_points.txt +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.22.0.dist-info → gammasimtools-0.23.0.dist-info}/top_level.txt +0 -0
|
@@ -13,8 +13,6 @@ from simtools.io import ascii_handler, io_handler
|
|
|
13
13
|
from simtools.simtel.simtel_config_writer import SimtelConfigWriter
|
|
14
14
|
from simtools.utils import names
|
|
15
15
|
|
|
16
|
-
__all__ = ["InvalidModelParameterError", "ModelParameter"]
|
|
17
|
-
|
|
18
16
|
|
|
19
17
|
class InvalidModelParameterError(Exception):
|
|
20
18
|
"""Exception for invalid model parameter."""
|
|
@@ -198,6 +196,31 @@ class ModelParameter:
|
|
|
198
196
|
|
|
199
197
|
return _parameter
|
|
200
198
|
|
|
199
|
+
def _create_quantity_for_value(self, value, unit):
|
|
200
|
+
"""
|
|
201
|
+
Create an astropy quantity for a single value and unit.
|
|
202
|
+
|
|
203
|
+
Parameters
|
|
204
|
+
----------
|
|
205
|
+
value: numeric or str
|
|
206
|
+
The value to create a quantity for.
|
|
207
|
+
unit: str or None
|
|
208
|
+
The unit string or None.
|
|
209
|
+
|
|
210
|
+
Returns
|
|
211
|
+
-------
|
|
212
|
+
astropy.Quantity or original value
|
|
213
|
+
Astropy quantity for numeric values with units,
|
|
214
|
+
original value for non-numeric values.
|
|
215
|
+
"""
|
|
216
|
+
if not isinstance(value, int | float):
|
|
217
|
+
return value
|
|
218
|
+
|
|
219
|
+
if unit is None or unit == "null":
|
|
220
|
+
return value * u.dimensionless_unscaled
|
|
221
|
+
|
|
222
|
+
return value * u.Unit(unit)
|
|
223
|
+
|
|
201
224
|
def get_parameter_value_with_unit(self, par_name):
|
|
202
225
|
"""
|
|
203
226
|
Get the value of an existing parameter of the model as an Astropy Quantity with its unit.
|
|
@@ -226,13 +249,12 @@ class ModelParameter:
|
|
|
226
249
|
if (isinstance(_value, (int | float))) or (len(_value) > len(_unit)):
|
|
227
250
|
return _value * u.Unit(_unit[0])
|
|
228
251
|
|
|
229
|
-
#
|
|
230
|
-
|
|
231
|
-
|
|
252
|
+
# Create list of quantities for multiple values with different units
|
|
253
|
+
return [
|
|
254
|
+
self._create_quantity_for_value(_value[i], _unit[i] if i < len(_unit) else None)
|
|
255
|
+
for i in range(len(_value))
|
|
232
256
|
]
|
|
233
257
|
|
|
234
|
-
return [_value[i] * _astropy_units[i] for i in range(len(_value))]
|
|
235
|
-
|
|
236
258
|
except (KeyError, TypeError, AttributeError) as exc:
|
|
237
259
|
self._logger.debug(
|
|
238
260
|
f"{exc} encountered for parameter {par_name}, returning only value without units."
|
|
@@ -550,6 +572,7 @@ class ModelParameter:
|
|
|
550
572
|
self.simtel_config_writer = SimtelConfigWriter(
|
|
551
573
|
site=self.site,
|
|
552
574
|
telescope_model_name=self.name,
|
|
575
|
+
telescope_design_model=self.design_model,
|
|
553
576
|
model_version=self.model_version,
|
|
554
577
|
label=self.label,
|
|
555
578
|
)
|
simtools/model/model_utils.py
CHANGED
|
@@ -8,11 +8,6 @@ from simtools.model.site_model import SiteModel
|
|
|
8
8
|
from simtools.model.telescope_model import TelescopeModel
|
|
9
9
|
from simtools.utils import names
|
|
10
10
|
|
|
11
|
-
__all__ = [
|
|
12
|
-
"compute_telescope_transmission",
|
|
13
|
-
"is_two_mirror_telescope",
|
|
14
|
-
]
|
|
15
|
-
|
|
16
11
|
|
|
17
12
|
def initialize_simulation_models(
|
|
18
13
|
label, db_config, model_version, site, telescope_name, calibration_device_name=None
|
simtools/model/site_model.py
CHANGED
|
@@ -175,6 +175,10 @@ class ReportGenerator:
|
|
|
175
175
|
f"Markdown report generated for {site} Telescope {telescope}: {self.output_path}"
|
|
176
176
|
)
|
|
177
177
|
|
|
178
|
+
# Also generate calibration device parameter comparison reports when using --all_telescopes
|
|
179
|
+
if self.args.get("all_telescopes"):
|
|
180
|
+
self._generate_calibration_device_parameter_reports()
|
|
181
|
+
|
|
178
182
|
def _generate_observatory_report_combinations(self) -> Generator[tuple[str, str], None, None]:
|
|
179
183
|
"""Generate combinations of sites and model versions for observatory reports.
|
|
180
184
|
|
|
@@ -215,3 +219,107 @@ class ReportGenerator:
|
|
|
215
219
|
"""Generate all observatory reports based on which --all_* flags are passed."""
|
|
216
220
|
for params in self._generate_observatory_report_combinations():
|
|
217
221
|
self._generate_single_observatory_report(*params)
|
|
222
|
+
|
|
223
|
+
def auto_generate_simulation_configuration_reports(self):
|
|
224
|
+
"""Generate simulation configuration reports for one or all model versions.
|
|
225
|
+
|
|
226
|
+
If --all_model_versions is set, produce reports for every model version in
|
|
227
|
+
the DB; otherwise produce reports only for the configured model_version.
|
|
228
|
+
"""
|
|
229
|
+
model_versions = (
|
|
230
|
+
self.db.get_model_versions()
|
|
231
|
+
if self.args.get("all_model_versions")
|
|
232
|
+
else [self.args["model_version"]]
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
for version in model_versions:
|
|
236
|
+
# update args and create a per-version output directory
|
|
237
|
+
self.args.update({"model_version": version})
|
|
238
|
+
output_path = Path(self.output_path) / str(version)
|
|
239
|
+
|
|
240
|
+
ReadParameters(
|
|
241
|
+
self.db_config, self.args, output_path
|
|
242
|
+
).produce_simulation_configuration_report()
|
|
243
|
+
|
|
244
|
+
logger.info(f"Configuration reports for (v{version}) produced: {output_path}")
|
|
245
|
+
|
|
246
|
+
def auto_generate_calibration_reports(self):
|
|
247
|
+
"""Generate calibration reports for one or all model versions.
|
|
248
|
+
|
|
249
|
+
Mirrors the pattern used by other auto_generate_* methods: if
|
|
250
|
+
--all_model_versions is set, produce reports for every model version in
|
|
251
|
+
the DB; otherwise produce reports only for the configured model_version.
|
|
252
|
+
"""
|
|
253
|
+
model_versions = (
|
|
254
|
+
self.db.get_model_versions()
|
|
255
|
+
if self.args.get("all_model_versions")
|
|
256
|
+
else [self.args["model_version"]]
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
for version in model_versions:
|
|
260
|
+
# update args and create a per-version output directory
|
|
261
|
+
self.args.update({"model_version": version})
|
|
262
|
+
output_path = Path(self.output_path) / str(version)
|
|
263
|
+
|
|
264
|
+
try:
|
|
265
|
+
ReadParameters(self.db_config, self.args, output_path).produce_calibration_reports()
|
|
266
|
+
logger.info(f"Calibration reports for (v{version}) produced: {output_path}")
|
|
267
|
+
except ValueError as err:
|
|
268
|
+
# Some model versions do not have calibration_devices in the DB;
|
|
269
|
+
msg = str(err)
|
|
270
|
+
if "calibration_devices" in msg and "zero results" in msg:
|
|
271
|
+
logger.info(
|
|
272
|
+
f"Skipping model version {version}: no calibration devices defined ({msg})"
|
|
273
|
+
)
|
|
274
|
+
continue
|
|
275
|
+
# re-raise unexpected ValueErrors
|
|
276
|
+
raise
|
|
277
|
+
|
|
278
|
+
def _generate_calibration_device_parameter_reports(self):
|
|
279
|
+
"""Generate parameter comparison reports for calibration devices for all model versions."""
|
|
280
|
+
# Get all model versions since no specific version is provided when using --all_telescopes
|
|
281
|
+
model_versions = self.db.get_model_versions()
|
|
282
|
+
|
|
283
|
+
for version in model_versions:
|
|
284
|
+
self._process_calibration_devices_for_version(version)
|
|
285
|
+
|
|
286
|
+
def _process_calibration_devices_for_version(self, version):
|
|
287
|
+
"""Process calibration devices for a specific model version."""
|
|
288
|
+
try:
|
|
289
|
+
# Get all calibration devices for this version
|
|
290
|
+
calibration_array_elements = self.db.get_array_elements(
|
|
291
|
+
version, collection="calibration_devices"
|
|
292
|
+
)
|
|
293
|
+
array_elements = calibration_array_elements.copy()
|
|
294
|
+
|
|
295
|
+
# Add design models
|
|
296
|
+
for element in calibration_array_elements:
|
|
297
|
+
design_model = self.db.get_design_model(version, element, "calibration_devices")
|
|
298
|
+
if design_model and design_model not in array_elements:
|
|
299
|
+
array_elements.append(design_model)
|
|
300
|
+
|
|
301
|
+
if array_elements:
|
|
302
|
+
# Create a copy of args with the current version for this iteration
|
|
303
|
+
version_args = self.args.copy()
|
|
304
|
+
version_args["model_version"] = version
|
|
305
|
+
|
|
306
|
+
# Generate parameter comparison reports for calibration devices
|
|
307
|
+
ReadParameters(
|
|
308
|
+
self.db_config, version_args, self.output_path
|
|
309
|
+
).generate_model_parameter_reports_for_devices(array_elements)
|
|
310
|
+
|
|
311
|
+
logger.info(
|
|
312
|
+
"Calibration device parameter reports generated for"
|
|
313
|
+
f" v{version}: {self.output_path}"
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
except ValueError as err:
|
|
317
|
+
# Some model versions may not have calibration_devices
|
|
318
|
+
msg = str(err)
|
|
319
|
+
if "calibration_devices" in msg and "zero results" in msg:
|
|
320
|
+
logger.info(
|
|
321
|
+
f"Skipping model version {version}: no calibration devices defined ({msg})"
|
|
322
|
+
)
|
|
323
|
+
return
|
|
324
|
+
# re-raise unexpected ValueErrors
|
|
325
|
+
raise
|
|
@@ -896,9 +896,6 @@ class ReadParameters:
|
|
|
896
896
|
output_filename, calibration_device, data, design_model
|
|
897
897
|
)
|
|
898
898
|
|
|
899
|
-
# produce parameter comparison reports (site-independent)
|
|
900
|
-
self._generate_model_parameter_reports_for_devices(array_elements)
|
|
901
|
-
|
|
902
899
|
def _collect_calibration_array_elements(self):
|
|
903
900
|
"""Return a list of calibration devices including their design models."""
|
|
904
901
|
calibration_array_elements = self.db.get_array_elements(
|
|
@@ -954,11 +951,8 @@ class ReadParameters:
|
|
|
954
951
|
|
|
955
952
|
self._write_to_file(display_group, file)
|
|
956
953
|
|
|
957
|
-
def
|
|
954
|
+
def generate_model_parameter_reports_for_devices(self, array_elements):
|
|
958
955
|
"""Create model-parameter comparison reports for calibration devices."""
|
|
959
|
-
new_output_path = Path(self.output_path).parent.parent / "parameters"
|
|
960
|
-
new_output_path.mkdir(parents=True, exist_ok=True)
|
|
961
|
-
self.output_path = new_output_path
|
|
962
956
|
for calibration_device in array_elements:
|
|
963
957
|
device_sites = names.get_site_from_array_element_name(calibration_device)
|
|
964
958
|
# parameters are site independent so just take the first site to read from db
|
|
@@ -7,8 +7,6 @@ from pathlib import Path
|
|
|
7
7
|
from simtools.io import io_handler
|
|
8
8
|
from simtools.runners.runner_services import RunnerServices
|
|
9
9
|
|
|
10
|
-
__all__ = ["CorsikaRunner", "MissingRequiredEntryInCorsikaConfigError"]
|
|
11
|
-
|
|
12
10
|
|
|
13
11
|
class MissingRequiredEntryInCorsikaConfigError(Exception):
|
|
14
12
|
"""Exception for missing required entry in corsika config."""
|
|
@@ -8,8 +8,6 @@ from pathlib import Path
|
|
|
8
8
|
import simtools.utils.general as gen
|
|
9
9
|
from simtools.runners.runner_services import RunnerServices
|
|
10
10
|
|
|
11
|
-
__all__ = ["InvalidOutputFileError", "SimtelExecutionError", "SimtelRunner"]
|
|
12
|
-
|
|
13
11
|
|
|
14
12
|
class SimtelExecutionError(Exception):
|
|
15
13
|
"""Exception for sim_telarray execution error."""
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
%YAML 1.2
|
|
2
|
+
---
|
|
3
|
+
title: Schema for transit_time_random model parameter
|
|
4
|
+
schema_version: 0.1.0
|
|
5
|
+
meta_schema: simpipe-schema
|
|
6
|
+
meta_schema_url: https://raw.githubusercontent.com/gammasim/simtools/main/src/simtools/schemas/model_parameter_and_data_schema.metaschema.yml
|
|
7
|
+
meta_schema_version: 0.1.0
|
|
8
|
+
name: transit_time_random
|
|
9
|
+
description: Event-wise and pixel-wise random fluctuations in the signal transit time.
|
|
10
|
+
data:
|
|
11
|
+
- type: float64
|
|
12
|
+
unit: ns
|
|
13
|
+
default: 0.
|
|
14
|
+
allowed_range:
|
|
15
|
+
min: 0.0
|
|
16
|
+
instrument:
|
|
17
|
+
class: Camera
|
|
18
|
+
activity:
|
|
19
|
+
setting:
|
|
20
|
+
- SetParameterFromExternal
|
|
21
|
+
validation:
|
|
22
|
+
- ValidateParameterByExpert
|
|
23
|
+
- ValidateCameraTimeResponse
|
|
24
|
+
source:
|
|
25
|
+
- Initial instrument setup
|
|
26
|
+
simulation_software:
|
|
27
|
+
- name: sim_telarray
|
|
28
|
+
- name: simtools
|
|
29
|
+
version: ">=0.22.0"
|
|
@@ -13,8 +13,6 @@ import simtools.version
|
|
|
13
13
|
from simtools.io import ascii_handler
|
|
14
14
|
from simtools.utils import names
|
|
15
15
|
|
|
16
|
-
__all__ = ["SimtelConfigWriter"]
|
|
17
|
-
|
|
18
16
|
|
|
19
17
|
def sim_telarray_random_seeds(seed, number):
|
|
20
18
|
"""
|
|
@@ -67,6 +65,7 @@ class SimtelConfigWriter:
|
|
|
67
65
|
model_version,
|
|
68
66
|
layout_name=None,
|
|
69
67
|
telescope_model_name=None,
|
|
68
|
+
telescope_design_model=None,
|
|
70
69
|
label=None,
|
|
71
70
|
simtel_path=None,
|
|
72
71
|
):
|
|
@@ -79,9 +78,12 @@ class SimtelConfigWriter:
|
|
|
79
78
|
self._label = label
|
|
80
79
|
self._layout_name = layout_name
|
|
81
80
|
self._telescope_model_name = telescope_model_name
|
|
81
|
+
self._telescope_design_model = telescope_design_model
|
|
82
82
|
self._simtel_path = simtel_path
|
|
83
83
|
|
|
84
|
-
def write_telescope_config_file(
|
|
84
|
+
def write_telescope_config_file(
|
|
85
|
+
self, config_file_path, parameters, telescope_name=None, telescope_design_model=None
|
|
86
|
+
):
|
|
85
87
|
"""
|
|
86
88
|
Write the sim_telarray config file for a single telescope.
|
|
87
89
|
|
|
@@ -93,22 +95,30 @@ class SimtelConfigWriter:
|
|
|
93
95
|
Model parameters
|
|
94
96
|
telescope_name: str
|
|
95
97
|
Name of the telescope (use self._telescope_model_name if None)
|
|
98
|
+
telescope_design_model: str
|
|
99
|
+
Telescope design model.
|
|
96
100
|
"""
|
|
97
101
|
self._logger.debug(f"Writing telescope config file {config_file_path}")
|
|
98
102
|
|
|
99
103
|
simtel_par = self._get_parameters_for_sim_telarray(parameters, config_file_path)
|
|
104
|
+
telescope_name = telescope_name or self._telescope_model_name
|
|
105
|
+
_telescope_design_model = telescope_design_model or self._telescope_design_model
|
|
100
106
|
|
|
101
107
|
with open(config_file_path, "w", encoding="utf-8") as file:
|
|
102
108
|
self._write_header(file, "TELESCOPE CONFIGURATION FILE")
|
|
103
109
|
|
|
104
|
-
telescope_name = telescope_name or self._telescope_model_name
|
|
105
110
|
file.write("#ifdef TELESCOPE\n")
|
|
106
111
|
file.write(f" echo Configuration for {telescope_name} - TELESCOPE $(TELESCOPE)\n")
|
|
107
112
|
file.write("#endif\n\n")
|
|
108
113
|
|
|
109
114
|
for simtel_name, simtel_value in simtel_par.items():
|
|
110
115
|
file.write(f"{simtel_name} = {self._get_value_string_for_simtel(simtel_value)}\n")
|
|
111
|
-
for meta in self._get_sim_telarray_metadata(
|
|
116
|
+
for meta in self._get_sim_telarray_metadata(
|
|
117
|
+
"telescope",
|
|
118
|
+
parameters,
|
|
119
|
+
telescope_name,
|
|
120
|
+
telescope_design_model=_telescope_design_model,
|
|
121
|
+
):
|
|
112
122
|
file.write(f"{meta}\n")
|
|
113
123
|
|
|
114
124
|
def _get_parameters_for_sim_telarray(self, parameters, config_file_path):
|
|
@@ -211,12 +221,17 @@ class SimtelConfigWriter:
|
|
|
211
221
|
value = "none" if value is None else value # simtel requires 'none'
|
|
212
222
|
if isinstance(value, bool):
|
|
213
223
|
value = 1 if value else 0
|
|
214
|
-
elif isinstance(value, (list, np.ndarray)):
|
|
224
|
+
elif isinstance(value, (list, np.ndarray)):
|
|
215
225
|
value = gen.convert_list_to_string(value, shorten_list=True)
|
|
216
226
|
return value
|
|
217
227
|
|
|
218
228
|
def _get_sim_telarray_metadata(
|
|
219
|
-
self,
|
|
229
|
+
self,
|
|
230
|
+
config_type,
|
|
231
|
+
model_parameters,
|
|
232
|
+
telescope_model_name,
|
|
233
|
+
additional_metadata=None,
|
|
234
|
+
telescope_design_model=None,
|
|
220
235
|
):
|
|
221
236
|
"""
|
|
222
237
|
Return sim_telarray metadata.
|
|
@@ -231,6 +246,8 @@ class SimtelConfigWriter:
|
|
|
231
246
|
Name of the telescope model
|
|
232
247
|
additional_metadata: dict
|
|
233
248
|
Dictionary with additional metadata to include using 'set'.
|
|
249
|
+
telescope_design_model: str
|
|
250
|
+
Name of the telescope design model.
|
|
234
251
|
|
|
235
252
|
Returns
|
|
236
253
|
-------
|
|
@@ -241,14 +258,15 @@ class SimtelConfigWriter:
|
|
|
241
258
|
f"config_release = {self._model_version} with simtools v{simtools.version.__version__}",
|
|
242
259
|
f"config_version = {self._model_version}",
|
|
243
260
|
]
|
|
261
|
+
telescope_design_model = telescope_design_model or "design_model_not_set"
|
|
244
262
|
if config_type == "telescope":
|
|
245
263
|
meta_parameters.extend(
|
|
246
264
|
[
|
|
247
|
-
f"camera_config_name = {
|
|
248
|
-
"camera_config_variant = ",
|
|
265
|
+
f"camera_config_name = {telescope_design_model}",
|
|
266
|
+
f"camera_config_variant = {telescope_model_name}",
|
|
249
267
|
f"camera_config_version = {self._model_version}",
|
|
250
|
-
f"optics_config_name = {
|
|
251
|
-
"optics_config_variant = ",
|
|
268
|
+
f"optics_config_name = {telescope_design_model}",
|
|
269
|
+
f"optics_config_variant = {telescope_model_name}",
|
|
252
270
|
f"optics_config_version = {self._model_version}",
|
|
253
271
|
]
|
|
254
272
|
)
|
|
@@ -521,7 +539,7 @@ class SimtelConfigWriter:
|
|
|
521
539
|
if simtel_name is not None:
|
|
522
540
|
file.write(f"{self.TAB}{simtel_name} = {value}\n")
|
|
523
541
|
for meta in self._get_sim_telarray_metadata(
|
|
524
|
-
"site", site_parameters,
|
|
542
|
+
"site", site_parameters, None, additional_metadata
|
|
525
543
|
):
|
|
526
544
|
file.write(f"{self.TAB}{meta}\n")
|
|
527
545
|
file.write("\n")
|
|
@@ -588,7 +606,7 @@ class SimtelConfigWriter:
|
|
|
588
606
|
trigger_lines[tel_type] += ", ".join(map(str, tel_list))
|
|
589
607
|
width = trigger_dict["width"]["value"] * u.Unit(trigger_dict["width"]["unit"]).to("ns")
|
|
590
608
|
trigger_lines[tel_type] += f" width {width}"
|
|
591
|
-
if trigger_dict.get("hard_stereo"):
|
|
609
|
+
if trigger_dict.get("hard_stereo", {}).get("value"):
|
|
592
610
|
trigger_lines[tel_type] += " hardstereo"
|
|
593
611
|
if all(trigger_dict["min_separation"][key] is not None for key in ["value", "unit"]):
|
|
594
612
|
min_sep = trigger_dict["min_separation"]["value"] * u.Unit(
|
|
@@ -105,8 +105,8 @@ def get_sim_telarray_telescope_id(telescope_name, file):
|
|
|
105
105
|
_, telescope_meta = read_sim_telarray_metadata(file)
|
|
106
106
|
telescope_name_to_sim_telarray_id = {}
|
|
107
107
|
for tel_id in telescope_meta.keys():
|
|
108
|
-
_optics_name = telescope_meta[tel_id].get("
|
|
109
|
-
_camera_name = telescope_meta[tel_id].get("
|
|
108
|
+
_optics_name = telescope_meta[tel_id].get("optics_config_variant", None)
|
|
109
|
+
_camera_name = telescope_meta[tel_id].get("camera_config_variant", None)
|
|
110
110
|
if _optics_name == _camera_name and _optics_name == telescope_name:
|
|
111
111
|
telescope_name_to_sim_telarray_id[telescope_name] = tel_id
|
|
112
112
|
|
|
@@ -132,7 +132,7 @@ def get_sim_telarray_telescope_id_to_telescope_name_mapping(file):
|
|
|
132
132
|
for i, (tel_id, meta) in enumerate(telescope_meta.items()):
|
|
133
133
|
try:
|
|
134
134
|
telescope_name = names.validate_array_element_name(
|
|
135
|
-
meta.get("
|
|
135
|
+
meta.get("optics_config_variant", f"Unknown-{tel_id}")
|
|
136
136
|
)
|
|
137
137
|
except ValueError:
|
|
138
138
|
telescope_name = _guess_telescope_name_for_legacy_files(i, file)
|
|
@@ -6,8 +6,6 @@ from simtools.io import io_handler
|
|
|
6
6
|
from simtools.runners.simtel_runner import InvalidOutputFileError, SimtelRunner
|
|
7
7
|
from simtools.utils.general import clear_default_sim_telarray_cfg_directories
|
|
8
8
|
|
|
9
|
-
__all__ = ["SimulatorArray"]
|
|
10
|
-
|
|
11
9
|
|
|
12
10
|
class SimulatorArray(SimtelRunner):
|
|
13
11
|
"""
|
|
@@ -73,41 +71,33 @@ class SimulatorArray(SimtelRunner):
|
|
|
73
71
|
command = self._common_run_command(run_number, weak_pointing)
|
|
74
72
|
|
|
75
73
|
if self.calibration_config:
|
|
76
|
-
command += self._make_run_command_for_calibration_simulations(
|
|
74
|
+
command += self._make_run_command_for_calibration_simulations()
|
|
77
75
|
else:
|
|
78
|
-
command += self._make_run_command_for_shower_simulations(
|
|
76
|
+
command += self._make_run_command_for_shower_simulations()
|
|
77
|
+
|
|
78
|
+
# "-C show=all" should be the last option
|
|
79
|
+
command += super().get_config_option("show", "all")
|
|
80
|
+
command += f" {input_file} | gzip > {self._log_file} 2>&1 || exit"
|
|
79
81
|
|
|
80
82
|
return clear_default_sim_telarray_cfg_directories(command)
|
|
81
83
|
|
|
82
|
-
def _make_run_command_for_shower_simulations(self
|
|
84
|
+
def _make_run_command_for_shower_simulations(self):
|
|
83
85
|
"""
|
|
84
86
|
Build and return the command to run sim_telarray shower simulations.
|
|
85
87
|
|
|
86
|
-
Parameters
|
|
87
|
-
----------
|
|
88
|
-
input_file: str
|
|
89
|
-
Full path of the input CORSIKA file
|
|
90
|
-
run_number: int (optional)
|
|
91
|
-
run number
|
|
92
|
-
weak_pointing: bool (optional)
|
|
93
|
-
Specify weak pointing option for sim_telarray.
|
|
94
|
-
|
|
95
88
|
Returns
|
|
96
89
|
-------
|
|
97
90
|
str
|
|
98
91
|
Command to run sim_telarray.
|
|
99
92
|
"""
|
|
100
|
-
|
|
101
|
-
command += f" | gzip > {self._log_file} 2>&1 || exit"
|
|
102
|
-
command += super().get_config_option(
|
|
93
|
+
return super().get_config_option(
|
|
103
94
|
"power_law",
|
|
104
95
|
SimulatorArray.get_power_law_for_sim_telarray_histograms(
|
|
105
96
|
self.corsika_config.primary_particle
|
|
106
97
|
),
|
|
107
98
|
)
|
|
108
|
-
return command
|
|
109
99
|
|
|
110
|
-
def _make_run_command_for_calibration_simulations(self
|
|
100
|
+
def _make_run_command_for_calibration_simulations(self):
|
|
111
101
|
"""Build sim_telarray command for calibration simulations."""
|
|
112
102
|
cfg = self.calibration_config
|
|
113
103
|
altitude = self.corsika_config.array_model.site_model.get_parameter_value_with_unit(
|
|
@@ -133,7 +123,6 @@ class SimulatorArray(SimtelRunner):
|
|
|
133
123
|
n_events = cfg.get("number_of_flasher_events", cfg["number_of_events"])
|
|
134
124
|
command += super().get_config_option("laser_events", n_events)
|
|
135
125
|
|
|
136
|
-
command += f" {input_file} | gzip > {self._log_file} 2>&1 || exit"
|
|
137
126
|
return command
|
|
138
127
|
|
|
139
128
|
def _common_run_command(self, run_number, weak_pointing=None):
|
|
@@ -162,7 +151,6 @@ class SimulatorArray(SimtelRunner):
|
|
|
162
151
|
)
|
|
163
152
|
elif self.sim_telarray_seeds and self.sim_telarray_seeds.get("seed"):
|
|
164
153
|
command += super().get_config_option("random_seed", self.sim_telarray_seeds["seed"])
|
|
165
|
-
command += super().get_config_option("show", "all")
|
|
166
154
|
command += super().get_config_option("output_file", output_file)
|
|
167
155
|
|
|
168
156
|
return command
|
|
@@ -15,8 +15,6 @@ from simtools.runners.simtel_runner import SimtelRunner
|
|
|
15
15
|
from simtools.utils.general import clear_default_sim_telarray_cfg_directories
|
|
16
16
|
from simtools.utils.geometry import fiducial_radius_from_shape
|
|
17
17
|
|
|
18
|
-
__all__ = ["SimulatorLightEmission"]
|
|
19
|
-
|
|
20
18
|
|
|
21
19
|
class SimulatorLightEmission(SimtelRunner):
|
|
22
20
|
"""
|
|
@@ -41,7 +39,7 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
41
39
|
simtel_path=light_emission_config.get("simtel_path"), label=label, corsika_config=None
|
|
42
40
|
)
|
|
43
41
|
|
|
44
|
-
self.output_directory = self.io_handler.get_output_directory(
|
|
42
|
+
self.output_directory = self.io_handler.get_output_directory()
|
|
45
43
|
|
|
46
44
|
self.telescope_model, self.site_model, self.calibration_model = (
|
|
47
45
|
initialize_simulation_models(
|
|
@@ -10,8 +10,6 @@ from simtools.runners.simtel_runner import SimtelRunner
|
|
|
10
10
|
from simtools.utils import names
|
|
11
11
|
from simtools.utils.general import clear_default_sim_telarray_cfg_directories
|
|
12
12
|
|
|
13
|
-
__all__ = ["SimulatorRayTracing"]
|
|
14
|
-
|
|
15
13
|
# pylint: disable=no-member
|
|
16
14
|
# The line above is needed because there are members which are created
|
|
17
15
|
# by adding them to the __dict__ of the class rather than directly.
|
simtools/simulator.py
CHANGED
|
@@ -22,11 +22,6 @@ from simtools.simtel.simulator_array import SimulatorArray
|
|
|
22
22
|
from simtools.testing.sim_telarray_metadata import assert_sim_telarray_metadata
|
|
23
23
|
from simtools.version import semver_to_int
|
|
24
24
|
|
|
25
|
-
__all__ = [
|
|
26
|
-
"InvalidRunsToSimulateError",
|
|
27
|
-
"Simulator",
|
|
28
|
-
]
|
|
29
|
-
|
|
30
25
|
|
|
31
26
|
class InvalidRunsToSimulateError(Exception):
|
|
32
27
|
"""Exception for invalid runs to simulate."""
|
simtools/testing/assertions.py
CHANGED
|
@@ -62,9 +62,9 @@ def assert_n_showers_and_energy_range(file):
|
|
|
62
62
|
|
|
63
63
|
simulated_energies = []
|
|
64
64
|
simulation_config = {}
|
|
65
|
-
with SimTelFile(file) as f:
|
|
65
|
+
with SimTelFile(file, skip_non_triggered=False) as f:
|
|
66
66
|
simulation_config = f.mc_run_headers[0]
|
|
67
|
-
for event in f
|
|
67
|
+
for event in f:
|
|
68
68
|
simulated_energies.append(event["mc_shower"]["energy"])
|
|
69
69
|
|
|
70
70
|
# The relative tolerance is set to 1% because ~0.5% shower simulations do not
|