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.
Files changed (85) hide show
  1. {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/METADATA +5 -2
  2. {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/RECORD +82 -74
  3. {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/entry_points.txt +4 -1
  5. simtools/_version.py +2 -2
  6. simtools/applications/db_add_simulation_model_from_repository_to_db.py +10 -1
  7. simtools/applications/derive_ctao_array_layouts.py +5 -5
  8. simtools/applications/derive_mirror_rnda.py +1 -1
  9. simtools/applications/generate_simtel_event_data.py +128 -46
  10. simtools/applications/merge_tables.py +102 -0
  11. simtools/applications/plot_array_layout.py +145 -258
  12. simtools/applications/plot_tabular_data.py +12 -1
  13. simtools/applications/plot_tabular_data_for_model_parameter.py +103 -0
  14. simtools/applications/production_derive_corsika_limits.py +78 -225
  15. simtools/applications/production_derive_statistics.py +77 -43
  16. simtools/applications/simulate_light_emission.py +1 -0
  17. simtools/applications/simulate_prod.py +30 -18
  18. simtools/applications/simulate_prod_htcondor_generator.py +0 -1
  19. simtools/applications/submit_array_layouts.py +93 -0
  20. simtools/applications/verify_simulation_model_production_tables.py +52 -0
  21. simtools/camera/camera_efficiency.py +3 -3
  22. simtools/configuration/commandline_parser.py +30 -35
  23. simtools/configuration/configurator.py +0 -4
  24. simtools/constants.py +2 -0
  25. simtools/corsika/corsika_config.py +17 -12
  26. simtools/corsika/primary_particle.py +46 -13
  27. simtools/data_model/metadata_collector.py +7 -3
  28. simtools/data_model/schema.py +15 -1
  29. simtools/db/db_handler.py +16 -11
  30. simtools/db/db_model_upload.py +2 -2
  31. simtools/io_operations/io_handler.py +2 -2
  32. simtools/io_operations/io_table_handler.py +345 -0
  33. simtools/job_execution/htcondor_script_generator.py +2 -2
  34. simtools/job_execution/job_manager.py +7 -121
  35. simtools/layout/array_layout_utils.py +389 -0
  36. simtools/model/array_model.py +10 -1
  37. simtools/model/model_repository.py +134 -0
  38. simtools/production_configuration/{calculate_statistical_errors_grid_point.py → calculate_statistical_uncertainties_grid_point.py} +101 -112
  39. simtools/production_configuration/derive_corsika_limits.py +239 -111
  40. simtools/production_configuration/derive_corsika_limits_grid.py +232 -0
  41. simtools/production_configuration/derive_production_statistics.py +57 -26
  42. simtools/production_configuration/derive_production_statistics_handler.py +70 -37
  43. simtools/production_configuration/interpolation_handler.py +296 -94
  44. simtools/ray_tracing/ray_tracing.py +7 -6
  45. simtools/reporting/docs_read_parameters.py +104 -62
  46. simtools/resources/array-element-ids.json +126 -0
  47. simtools/runners/corsika_simtel_runner.py +4 -1
  48. simtools/runners/runner_services.py +5 -4
  49. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +5 -1
  50. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +41 -0
  51. simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +43 -0
  52. simtools/schemas/model_parameters/camera_filter.schema.yml +10 -0
  53. simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +10 -0
  54. simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +31 -0
  55. simtools/schemas/model_parameters/dsum_threshold.schema.yml +41 -0
  56. simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +12 -0
  57. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +10 -0
  58. simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +10 -0
  59. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +12 -0
  60. simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +19 -0
  61. simtools/schemas/model_parameters/quantum_efficiency.schema.yml +10 -0
  62. simtools/schemas/plot_configuration.metaschema.yml +46 -57
  63. simtools/schemas/production_configuration_metrics.schema.yml +2 -2
  64. simtools/simtel/simtel_config_writer.py +34 -14
  65. simtools/simtel/simtel_io_event_reader.py +301 -194
  66. simtools/simtel/simtel_io_event_writer.py +237 -221
  67. simtools/simtel/simtel_io_file_info.py +9 -4
  68. simtools/simtel/simtel_io_metadata.py +119 -8
  69. simtools/simtel/simulator_array.py +2 -2
  70. simtools/simtel/simulator_light_emission.py +79 -34
  71. simtools/simtel/simulator_ray_tracing.py +2 -2
  72. simtools/simulator.py +101 -68
  73. simtools/testing/validate_output.py +4 -1
  74. simtools/utils/general.py +1 -3
  75. simtools/utils/names.py +76 -7
  76. simtools/visualization/plot_array_layout.py +242 -0
  77. simtools/visualization/plot_pixels.py +680 -0
  78. simtools/visualization/plot_tables.py +81 -2
  79. simtools/visualization/visualize.py +3 -219
  80. simtools/applications/production_generate_simulation_config.py +0 -152
  81. simtools/layout/ctao_array_layouts.py +0 -172
  82. simtools/production_configuration/generate_simulation_config.py +0 -158
  83. {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/licenses/LICENSE +0 -0
  84. {gammasimtools-0.16.0.dist-info → gammasimtools-0.18.0.dist-info}/top_level.txt +0 -0
  85. /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 = decode(o.parse())
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
- return clean_meta(global_meta), {
61
- tel_id: clean_meta(meta) for tel_id, meta in telescope_meta.items()
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="output", run_number=run_number)
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="output", run_number=run_number)
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") if not test else 1e7
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
- # use DB coordinates later
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.get_parameter_value(
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
- self._calibration_model.get_parameter_value("array_element_position_ground") * u.m
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
- x_tel, y_tel, z_tel = (
172
- self._telescope_model.get_parameter_value("array_element_position_ground") * u.m
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
- _model_directory = self.io_handler.get_output_directory(self.label, "model")
175
- command = f" rm {self.output_directory}/"
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
- x_origin = x_cal - x_tel
192
- y_origin = y_cal - y_tel
193
- z_origin = z_cal - z_tel
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
- # same wavelength as for laser
204
- command += f" -s {self._calibration_model.get_parameter_value('laser_wavelength')}"
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
- # pulse
207
- command += (
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 += " -a isotropic" # angular distribution
246
+ command += f" -p Gauss:{led_pulse_sigtime.to(u.ns).value}"
247
+ command += " -a isotropic"
211
248
 
212
- command += f" -A {_model_directory}/"
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
- command += (
221
- f" --spectrum {self._calibration_model.get_parameter_value('laser_wavelength')}"
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
- command += f"{self._calibration_model.get_parameter_value('laser_pulse_sigtime')}"
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]}" # convention north (x) towards east (-y)
238
- command += f" --atmosphere {_model_directory}/"
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", self._site_model.get_parameter_value("corsika_observation_level")
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.get_parameter_value(
571
+ x_cal, y_cal, z_cal = self._calibration_model.get_parameter_value_with_unit(
530
572
  "array_element_position_ground"
531
573
  )
532
- x_tel, y_tel, z_tel = self._telescope_model.get_parameter_value(
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, "ray-tracing")
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,