gammasimtools 0.16.0__py3-none-any.whl → 0.18.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.16.0.dist-info → gammasimtools-0.18.0.dist-info}/METADATA +5 -2
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/RECORD +82 -74
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/entry_points.txt +4 -1
- simtools/_version.py +2 -2
- simtools/applications/db_add_simulation_model_from_repository_to_db.py +10 -1
- simtools/applications/derive_ctao_array_layouts.py +5 -5
- simtools/applications/derive_mirror_rnda.py +1 -1
- simtools/applications/generate_simtel_event_data.py +128 -46
- simtools/applications/merge_tables.py +102 -0
- simtools/applications/plot_array_layout.py +145 -258
- simtools/applications/plot_tabular_data.py +12 -1
- simtools/applications/plot_tabular_data_for_model_parameter.py +103 -0
- simtools/applications/production_derive_corsika_limits.py +78 -225
- simtools/applications/production_derive_statistics.py +77 -43
- simtools/applications/simulate_light_emission.py +1 -0
- simtools/applications/simulate_prod.py +30 -18
- simtools/applications/simulate_prod_htcondor_generator.py +0 -1
- simtools/applications/submit_array_layouts.py +93 -0
- simtools/applications/verify_simulation_model_production_tables.py +52 -0
- simtools/camera/camera_efficiency.py +3 -3
- simtools/configuration/commandline_parser.py +30 -35
- simtools/configuration/configurator.py +0 -4
- simtools/constants.py +2 -0
- simtools/corsika/corsika_config.py +17 -12
- simtools/corsika/primary_particle.py +46 -13
- simtools/data_model/metadata_collector.py +7 -3
- simtools/data_model/schema.py +15 -1
- simtools/db/db_handler.py +16 -11
- simtools/db/db_model_upload.py +2 -2
- simtools/io_operations/io_handler.py +2 -2
- simtools/io_operations/io_table_handler.py +345 -0
- simtools/job_execution/htcondor_script_generator.py +2 -2
- simtools/job_execution/job_manager.py +7 -121
- simtools/layout/array_layout_utils.py +389 -0
- simtools/model/array_model.py +10 -1
- simtools/model/model_repository.py +134 -0
- simtools/production_configuration/{calculate_statistical_errors_grid_point.py → calculate_statistical_uncertainties_grid_point.py} +101 -112
- simtools/production_configuration/derive_corsika_limits.py +239 -111
- simtools/production_configuration/derive_corsika_limits_grid.py +232 -0
- simtools/production_configuration/derive_production_statistics.py +57 -26
- simtools/production_configuration/derive_production_statistics_handler.py +70 -37
- simtools/production_configuration/interpolation_handler.py +296 -94
- simtools/ray_tracing/ray_tracing.py +7 -6
- simtools/reporting/docs_read_parameters.py +104 -62
- simtools/resources/array-element-ids.json +126 -0
- simtools/runners/corsika_simtel_runner.py +4 -1
- simtools/runners/runner_services.py +5 -4
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +5 -1
- simtools/schemas/model_parameters/atmospheric_profile.schema.yml +41 -0
- simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +43 -0
- simtools/schemas/model_parameters/camera_filter.schema.yml +10 -0
- simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +10 -0
- simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +31 -0
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +41 -0
- simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +12 -0
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +10 -0
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +10 -0
- simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +12 -0
- simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +19 -0
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +10 -0
- simtools/schemas/plot_configuration.metaschema.yml +46 -57
- simtools/schemas/production_configuration_metrics.schema.yml +2 -2
- simtools/simtel/simtel_config_writer.py +34 -14
- simtools/simtel/simtel_io_event_reader.py +301 -194
- simtools/simtel/simtel_io_event_writer.py +237 -221
- simtools/simtel/simtel_io_file_info.py +9 -4
- simtools/simtel/simtel_io_metadata.py +119 -8
- simtools/simtel/simulator_array.py +2 -2
- simtools/simtel/simulator_light_emission.py +79 -34
- simtools/simtel/simulator_ray_tracing.py +2 -2
- simtools/simulator.py +101 -68
- simtools/testing/validate_output.py +4 -1
- simtools/utils/general.py +1 -3
- simtools/utils/names.py +76 -7
- simtools/visualization/plot_array_layout.py +242 -0
- simtools/visualization/plot_pixels.py +680 -0
- simtools/visualization/plot_tables.py +81 -2
- simtools/visualization/visualize.py +3 -219
- simtools/applications/production_generate_simulation_config.py +0 -152
- simtools/layout/ctao_array_layouts.py +0 -172
- simtools/production_configuration/generate_simulation_config.py +0 -158
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/top_level.txt +0 -0
- /simtools/{schemas → resources}/array_elements.yml +0 -0
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
2
|
"""Read metadata from sim_telarray files."""
|
|
3
3
|
|
|
4
|
+
import logging
|
|
5
|
+
import re
|
|
4
6
|
from functools import cache
|
|
5
7
|
|
|
6
8
|
from eventio import EventIOFile
|
|
9
|
+
from eventio.iact import InputCard
|
|
7
10
|
from eventio.simtel import HistoryMeta
|
|
8
11
|
|
|
12
|
+
from simtools.utils import names
|
|
13
|
+
|
|
14
|
+
_logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
9
16
|
|
|
10
17
|
@cache
|
|
11
18
|
def read_sim_telarray_metadata(file, encoding="utf8"):
|
|
@@ -28,10 +35,6 @@ def read_sim_telarray_metadata(file, encoding="utf8"):
|
|
|
28
35
|
telescope_meta: dict
|
|
29
36
|
Dictionary of telescope metadata, keyed by telescope ID.
|
|
30
37
|
"""
|
|
31
|
-
|
|
32
|
-
def decode(meta):
|
|
33
|
-
return {k.decode(encoding): v.decode(encoding) for k, v in meta.items()}
|
|
34
|
-
|
|
35
38
|
global_meta = None
|
|
36
39
|
telescope_meta = {}
|
|
37
40
|
|
|
@@ -45,7 +48,7 @@ def read_sim_telarray_metadata(file, encoding="utf8"):
|
|
|
45
48
|
break
|
|
46
49
|
continue
|
|
47
50
|
|
|
48
|
-
meta =
|
|
51
|
+
meta = _decode_dictionary(o.parse(), encoding=encoding)
|
|
49
52
|
if o.header.id == -1:
|
|
50
53
|
global_meta = meta
|
|
51
54
|
else:
|
|
@@ -57,9 +60,28 @@ def read_sim_telarray_metadata(file, encoding="utf8"):
|
|
|
57
60
|
return {k: v.strip() if isinstance(v, str) else v for k, v in meta.items()}
|
|
58
61
|
|
|
59
62
|
# keys to lower case and strip leading '*', trailing spaces
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
try:
|
|
64
|
+
return clean_meta(global_meta), {
|
|
65
|
+
tel_id: clean_meta(meta) for tel_id, meta in telescope_meta.items()
|
|
66
|
+
}
|
|
67
|
+
except AttributeError as e:
|
|
68
|
+
raise AttributeError(f"Error reading metadata from file {file}: {e}") from e
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _decode_dictionary(meta, encoding="utf8"):
|
|
72
|
+
"""Decode metadata dictionary."""
|
|
73
|
+
|
|
74
|
+
def safe_decode(byte_str, encoding, errors="ignore"):
|
|
75
|
+
return byte_str.decode(encoding, errors=errors)
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
return {k.decode(encoding, errors="ignore"): v.decode(encoding) for k, v in meta.items()}
|
|
79
|
+
except UnicodeDecodeError as e:
|
|
80
|
+
_logger.warning(
|
|
81
|
+
f"Failed to decode metadata with encoding {encoding}: {e}. "
|
|
82
|
+
"Falling back to 'utf-8' with errors='ignore'."
|
|
83
|
+
)
|
|
84
|
+
return {safe_decode(k, encoding): safe_decode(v, encoding) for k, v in meta.items()}
|
|
63
85
|
|
|
64
86
|
|
|
65
87
|
def get_sim_telarray_telescope_id(telescope_name, file):
|
|
@@ -89,3 +111,92 @@ def get_sim_telarray_telescope_id(telescope_name, file):
|
|
|
89
111
|
telescope_name_to_sim_telarray_id[telescope_name] = tel_id
|
|
90
112
|
|
|
91
113
|
return telescope_name_to_sim_telarray_id.get(telescope_name, None)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def get_sim_telarray_telescope_id_to_telescope_name_mapping(file):
|
|
117
|
+
"""
|
|
118
|
+
Return a mapping of telescope IDs to telescope names from a sim_telarray file.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
file: str
|
|
123
|
+
Path to the sim_telarray file.
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
dict
|
|
128
|
+
Dictionary mapping telescope IDs to telescope names.
|
|
129
|
+
"""
|
|
130
|
+
_, telescope_meta = read_sim_telarray_metadata(file)
|
|
131
|
+
telescope_map = {}
|
|
132
|
+
for i, (tel_id, meta) in enumerate(telescope_meta.items()):
|
|
133
|
+
try:
|
|
134
|
+
telescope_name = names.validate_array_element_name(
|
|
135
|
+
meta.get("optics_config_name", f"Unknown-{tel_id}")
|
|
136
|
+
)
|
|
137
|
+
except ValueError:
|
|
138
|
+
telescope_name = _guess_telescope_name_for_legacy_files(i, file)
|
|
139
|
+
if telescope_name is not None:
|
|
140
|
+
telescope_map[tel_id] = telescope_name
|
|
141
|
+
|
|
142
|
+
return telescope_map
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _guess_telescope_name_for_legacy_files(tel_counter, file):
|
|
146
|
+
"""
|
|
147
|
+
Guess telescope names for legacy prod6 sim_telarray files with incomplete metadata.
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
tel_counter: int
|
|
152
|
+
Telescope counter, used to index into the telescope list.
|
|
153
|
+
file: str, Path
|
|
154
|
+
Path to the sim_telarray file.
|
|
155
|
+
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
str, None
|
|
159
|
+
Guessed telescope name or None if not found.
|
|
160
|
+
"""
|
|
161
|
+
telescope_list = _get_telescope_list_from_input_card(file)
|
|
162
|
+
try:
|
|
163
|
+
return names.validate_array_element_name(telescope_list[tel_counter])
|
|
164
|
+
except (IndexError, ValueError):
|
|
165
|
+
pass
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@cache
|
|
170
|
+
def _get_telescope_list_from_input_card(file):
|
|
171
|
+
r"""
|
|
172
|
+
Return telescope list from CORSIKA input card.
|
|
173
|
+
|
|
174
|
+
Note hardwired regex pattern with telescope naming convention.
|
|
175
|
+
This function is intended for legacy files generated for prod6,
|
|
176
|
+
where metadata is incomplete.
|
|
177
|
+
|
|
178
|
+
Expected format in input card:
|
|
179
|
+
|
|
180
|
+
.. code-block:: console
|
|
181
|
+
TELESCOPE -70.91E2 -52.35E2 45.00E2 12.50E2 # (ID=1) LSTN 01 2B5\n
|
|
182
|
+
|
|
183
|
+
Parameters
|
|
184
|
+
----------
|
|
185
|
+
file: str, Path
|
|
186
|
+
Path to the sim_telarray file.
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
list
|
|
191
|
+
List of telescope names as found in CORSIKA input card.
|
|
192
|
+
"""
|
|
193
|
+
with EventIOFile(file) as f:
|
|
194
|
+
for o in f:
|
|
195
|
+
if isinstance(o, InputCard):
|
|
196
|
+
input_card = o.parse().decode("utf-8")
|
|
197
|
+
regex = (
|
|
198
|
+
r"TELESCOPE\s+[-\d.E]+\s+[-\d.E]+\s+[-\d.E]+\s+[-\d.E]+\s+"
|
|
199
|
+
r"# \(ID=\d+\)\s+(LST[N|S]|MST[N|S]|S[S|C]TS)\s+([^\s]+)"
|
|
200
|
+
)
|
|
201
|
+
return [f"{m[0]}-{m[1]}" for m in re.findall(regex, input_card)]
|
|
202
|
+
return []
|
|
@@ -71,7 +71,7 @@ class SimulatorArray(SimtelRunner):
|
|
|
71
71
|
config_dir = self.corsika_config.array_model.get_config_directory()
|
|
72
72
|
self._log_file = self.get_file_name(file_type="log", run_number=run_number)
|
|
73
73
|
histogram_file = self.get_file_name(file_type="histogram", run_number=run_number)
|
|
74
|
-
output_file = self.get_file_name(file_type="
|
|
74
|
+
output_file = self.get_file_name(file_type="simtel_output", run_number=run_number)
|
|
75
75
|
self.corsika_config.array_model.export_all_simtel_config_files()
|
|
76
76
|
|
|
77
77
|
command = str(self._simtel_path.joinpath("sim_telarray/bin/sim_telarray"))
|
|
@@ -124,7 +124,7 @@ class SimulatorArray(SimtelRunner):
|
|
|
124
124
|
InvalidOutputFileError
|
|
125
125
|
If simtel output file does not exist.
|
|
126
126
|
"""
|
|
127
|
-
output_file = self.get_file_name(file_type="
|
|
127
|
+
output_file = self.get_file_name(file_type="simtel_output", run_number=run_number)
|
|
128
128
|
if not output_file.exists():
|
|
129
129
|
msg = f"sim_telarray output file {output_file} does not exist."
|
|
130
130
|
self._logger.error(msg)
|
|
@@ -46,6 +46,7 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
46
46
|
self._telescope_model = telescope_model
|
|
47
47
|
|
|
48
48
|
self.label = label if label is not None else self._telescope_model.label
|
|
49
|
+
self.test = test
|
|
49
50
|
|
|
50
51
|
self._calibration_model = calibration_model
|
|
51
52
|
self._site_model = site_model
|
|
@@ -56,7 +57,9 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
56
57
|
self._rep_number = 0
|
|
57
58
|
self.runs = 1
|
|
58
59
|
self.photons_per_run = (
|
|
59
|
-
self._calibration_model.get_parameter_value("photons_per_run")
|
|
60
|
+
(self._calibration_model.get_parameter_value("photons_per_run"))
|
|
61
|
+
if not self.test
|
|
62
|
+
else 1e8
|
|
60
63
|
)
|
|
61
64
|
|
|
62
65
|
self.le_application = le_application
|
|
@@ -64,7 +67,6 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
64
67
|
self.distance = None
|
|
65
68
|
self.light_source_type = light_source_type
|
|
66
69
|
self._telescope_model.write_sim_telarray_config_file(additional_model=site_model)
|
|
67
|
-
self.test = test
|
|
68
70
|
|
|
69
71
|
@staticmethod
|
|
70
72
|
def light_emission_default_configuration():
|
|
@@ -119,14 +121,15 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
119
121
|
list
|
|
120
122
|
The pointing vector from the calibration device to the telescope.
|
|
121
123
|
"""
|
|
122
|
-
|
|
123
|
-
x_cal, y_cal, z_cal = self._calibration_model.get_parameter_value(
|
|
124
|
+
x_cal, y_cal, z_cal = self._calibration_model.get_parameter_value_with_unit(
|
|
124
125
|
"array_element_position_ground"
|
|
125
126
|
)
|
|
127
|
+
x_cal, y_cal, z_cal = [coord.to(u.m).value for coord in (x_cal, y_cal, z_cal)]
|
|
126
128
|
cal_vect = np.array([x_cal, y_cal, z_cal])
|
|
127
|
-
x_tel, y_tel, z_tel = self._telescope_model.
|
|
129
|
+
x_tel, y_tel, z_tel = self._telescope_model.get_parameter_value_with_unit(
|
|
128
130
|
"array_element_position_ground"
|
|
129
131
|
)
|
|
132
|
+
x_tel, y_tel, z_tel = [coord.to(u.m).value for coord in (x_tel, y_tel, z_tel)]
|
|
130
133
|
|
|
131
134
|
tel_vect = np.array([x_tel, y_tel, z_tel])
|
|
132
135
|
|
|
@@ -153,6 +156,30 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
153
156
|
)
|
|
154
157
|
return pointing_vector.tolist(), [tel_theta, tel_phi, laser_theta, laser_phi]
|
|
155
158
|
|
|
159
|
+
def _write_telpos_file(self):
|
|
160
|
+
"""
|
|
161
|
+
Write the telescope positions to a telpos file.
|
|
162
|
+
|
|
163
|
+
The file will contain lines in the format: x y z r in cm
|
|
164
|
+
|
|
165
|
+
Returns
|
|
166
|
+
-------
|
|
167
|
+
Path
|
|
168
|
+
The path to the generated telpos file.
|
|
169
|
+
"""
|
|
170
|
+
telpos_file = self.output_directory.joinpath("telpos.dat")
|
|
171
|
+
x_tel, y_tel, z_tel = self._telescope_model.get_parameter_value_with_unit(
|
|
172
|
+
"array_element_position_ground"
|
|
173
|
+
)
|
|
174
|
+
x_tel, y_tel, z_tel = [coord.to(u.cm).value for coord in (x_tel, y_tel, z_tel)]
|
|
175
|
+
|
|
176
|
+
radius = self._telescope_model.get_parameter_value_with_unit("telescope_sphere_radius")
|
|
177
|
+
radius = radius.to(u.cm).value # Convert radius to cm
|
|
178
|
+
with telpos_file.open("w", encoding="utf-8") as file:
|
|
179
|
+
file.write(f"{x_tel} {y_tel} {z_tel} {radius}\n")
|
|
180
|
+
|
|
181
|
+
return telpos_file
|
|
182
|
+
|
|
156
183
|
def _make_light_emission_script(self):
|
|
157
184
|
"""
|
|
158
185
|
Create the light emission script to run the light emission package.
|
|
@@ -165,17 +192,28 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
165
192
|
str
|
|
166
193
|
The commands to run the Light Emission package
|
|
167
194
|
"""
|
|
168
|
-
x_cal, y_cal, z_cal = (
|
|
169
|
-
|
|
195
|
+
x_cal, y_cal, z_cal = self._calibration_model.get_parameter_value_with_unit(
|
|
196
|
+
"array_element_position_ground"
|
|
197
|
+
)
|
|
198
|
+
x_tel, y_tel, z_tel = self._telescope_model.get_parameter_value_with_unit(
|
|
199
|
+
"array_element_position_ground"
|
|
170
200
|
)
|
|
171
|
-
|
|
172
|
-
|
|
201
|
+
|
|
202
|
+
config_directory = self.io_handler.get_output_directory(
|
|
203
|
+
label=self.label, sub_dir=f"model/{self._site_model.model_version}"
|
|
173
204
|
)
|
|
174
|
-
|
|
175
|
-
|
|
205
|
+
|
|
206
|
+
telpos_file = self._write_telpos_file()
|
|
207
|
+
|
|
208
|
+
command = f"rm {self.output_directory}/"
|
|
176
209
|
command += f"{self.le_application[0]}_{self.le_application[1]}.simtel.gz\n"
|
|
177
210
|
command += str(self._simtel_path.joinpath("sim_telarray/LightEmission/"))
|
|
178
211
|
command += f"/{self.le_application[0]}"
|
|
212
|
+
corsika_observation_level = self._site_model.get_parameter_value_with_unit(
|
|
213
|
+
"corsika_observation_level"
|
|
214
|
+
)
|
|
215
|
+
command += f" -h {corsika_observation_level.to(u.m).value}"
|
|
216
|
+
command += f" --telpos-file {telpos_file}"
|
|
179
217
|
|
|
180
218
|
if self.light_source_type == "led":
|
|
181
219
|
if self.le_application[1] == "variable":
|
|
@@ -188,28 +226,27 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
188
226
|
command += f" -n {self.photons_per_run}"
|
|
189
227
|
|
|
190
228
|
elif self.le_application[1] == "layout":
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
# light_source coordinates relative to telescope
|
|
195
|
-
command += f" -x {x_origin.to(u.cm).value}"
|
|
196
|
-
command += f" -y {y_origin.to(u.cm).value}"
|
|
197
|
-
command += f" -z {z_origin.to(u.cm).value}"
|
|
229
|
+
command += f" -x {x_cal.to(u.cm).value}"
|
|
230
|
+
command += f" -y {y_cal.to(u.cm).value}"
|
|
231
|
+
command += f" -z {z_cal.to(u.cm).value}"
|
|
198
232
|
pointing_vector = self.calibration_pointing_direction()[0]
|
|
199
233
|
command += f" -d {','.join(map(str, pointing_vector))}"
|
|
200
234
|
|
|
201
235
|
command += f" -n {self.photons_per_run}"
|
|
236
|
+
self._logger.info(f"Photons per run: {self.photons_per_run} ")
|
|
202
237
|
|
|
203
|
-
|
|
204
|
-
|
|
238
|
+
laser_wavelength = self._calibration_model.get_parameter_value_with_unit(
|
|
239
|
+
"laser_wavelength"
|
|
240
|
+
)
|
|
241
|
+
command += f" -s {int(laser_wavelength.to(u.nm).value)}"
|
|
205
242
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
f" -p Gauss:{self._calibration_model.get_parameter_value('led_pulse_sigtime')}"
|
|
243
|
+
led_pulse_sigtime = self._calibration_model.get_parameter_value_with_unit(
|
|
244
|
+
"led_pulse_sigtime"
|
|
209
245
|
)
|
|
210
|
-
command += " -
|
|
246
|
+
command += f" -p Gauss:{led_pulse_sigtime.to(u.ns).value}"
|
|
247
|
+
command += " -a isotropic"
|
|
211
248
|
|
|
212
|
-
command += f" -A {
|
|
249
|
+
command += f" -A {config_directory}/"
|
|
213
250
|
command += f"{self._telescope_model.get_parameter_value('atmospheric_profile')}"
|
|
214
251
|
|
|
215
252
|
elif self.light_source_type == "laser":
|
|
@@ -217,11 +254,13 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
217
254
|
command += " --bunches 2500000"
|
|
218
255
|
command += " --step 0.1"
|
|
219
256
|
command += " --bunchsize 1"
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
)
|
|
257
|
+
spectrum = self._calibration_model.get_parameter_value_with_unit("laser_wavelength")
|
|
258
|
+
command += f" --spectrum {int(spectrum.to(u.nm).value)}"
|
|
223
259
|
command += " --lightpulse Gauss:"
|
|
224
|
-
|
|
260
|
+
pulse_sigtime = self._calibration_model.get_parameter_value_with_unit(
|
|
261
|
+
"laser_pulse_sigtime"
|
|
262
|
+
)
|
|
263
|
+
command += f"{pulse_sigtime.to(u.ns).value}"
|
|
225
264
|
x_origin = x_cal - x_tel
|
|
226
265
|
y_origin = y_cal - y_tel
|
|
227
266
|
z_origin = z_cal - z_tel
|
|
@@ -234,8 +273,8 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
234
273
|
command += f" --telescope-theta {angle_theta}"
|
|
235
274
|
command += f" --telescope-phi {angle_phi}"
|
|
236
275
|
command += f" --laser-theta {90 - angles[2]}"
|
|
237
|
-
command += f" --laser-phi {angles[3]}"
|
|
238
|
-
command += f" --atmosphere {
|
|
276
|
+
command += f" --laser-phi {angles[3]}"
|
|
277
|
+
command += f" --atmosphere {config_directory}/"
|
|
239
278
|
command += f"{self._telescope_model.get_parameter_value('atmospheric_profile')}"
|
|
240
279
|
command += f" -o {self.output_directory}/{self.le_application[0]}.iact.gz"
|
|
241
280
|
command += "\n"
|
|
@@ -264,7 +303,10 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
264
303
|
command += " -DNUM_TELESCOPES=1"
|
|
265
304
|
|
|
266
305
|
command += super().get_config_option(
|
|
267
|
-
"altitude",
|
|
306
|
+
"altitude",
|
|
307
|
+
self._site_model.get_parameter_value_with_unit("corsika_observation_level")
|
|
308
|
+
.to(u.m)
|
|
309
|
+
.value,
|
|
268
310
|
)
|
|
269
311
|
command += super().get_config_option(
|
|
270
312
|
"atmospheric_transmission",
|
|
@@ -526,15 +568,18 @@ class SimulatorLightEmission(SimtelRunner):
|
|
|
526
568
|
"""
|
|
527
569
|
if not self.light_emission_config:
|
|
528
570
|
# Layout positions: Use DB coordinates
|
|
529
|
-
x_cal, y_cal, z_cal = self._calibration_model.
|
|
571
|
+
x_cal, y_cal, z_cal = self._calibration_model.get_parameter_value_with_unit(
|
|
530
572
|
"array_element_position_ground"
|
|
531
573
|
)
|
|
532
|
-
|
|
574
|
+
x_cal, y_cal, z_cal = [coord.to(u.m).value for coord in (x_cal, y_cal, z_cal)]
|
|
575
|
+
x_tel, y_tel, z_tel = self._telescope_model.get_parameter_value_with_unit(
|
|
533
576
|
"array_element_position_ground"
|
|
534
577
|
)
|
|
578
|
+
x_tel, y_tel, z_tel = [coord.to(u.m).value for coord in (x_tel, y_tel, z_tel)]
|
|
535
579
|
tel_vect = np.array([x_tel, y_tel, z_tel])
|
|
536
580
|
cal_vect = np.array([x_cal, y_cal, z_cal])
|
|
537
581
|
distance = np.linalg.norm(cal_vect - tel_vect)
|
|
582
|
+
print("Distance between telescope and calibration device:", distance * u.m)
|
|
538
583
|
return [distance * u.m]
|
|
539
584
|
|
|
540
585
|
# Variable positions: Calculate distances for all positions
|
|
@@ -61,7 +61,7 @@ class SimulatorRayTracing(SimtelRunner):
|
|
|
61
61
|
self.label = label if label is not None else self.telescope_model.label
|
|
62
62
|
|
|
63
63
|
self.io_handler = io_handler.IOHandler()
|
|
64
|
-
self._base_directory = self.io_handler.get_output_directory(self.label, "
|
|
64
|
+
self._base_directory = self.io_handler.get_output_directory(self.label, "ray_tracing")
|
|
65
65
|
|
|
66
66
|
self.config = (
|
|
67
67
|
self._config_to_namedtuple(config_data)
|
|
@@ -93,7 +93,7 @@ class SimulatorRayTracing(SimtelRunner):
|
|
|
93
93
|
# Files will be named _base_file = self.__dict__['_' + base + 'File']
|
|
94
94
|
for base_name in ["stars", "photons", "log"]:
|
|
95
95
|
file_name = names.generate_file_name(
|
|
96
|
-
file_type=base_name,
|
|
96
|
+
file_type=f"ray_tracing_{base_name}",
|
|
97
97
|
suffix=".log" if base_name == "log" else ".lis",
|
|
98
98
|
site=self.telescope_model.site,
|
|
99
99
|
telescope_model_name=self.telescope_model.name,
|