gammasimtools 0.19.0__py3-none-any.whl → 0.20.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 (47) hide show
  1. {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/METADATA +1 -3
  2. {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/RECORD +43 -41
  3. {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/entry_points.txt +2 -2
  4. simtools/_version.py +2 -2
  5. simtools/applications/calculate_incident_angles.py +182 -0
  6. simtools/applications/db_add_simulation_model_from_repository_to_db.py +17 -14
  7. simtools/applications/db_add_value_from_json_to_db.py +6 -9
  8. simtools/applications/db_generate_compound_indexes.py +7 -3
  9. simtools/applications/db_get_file_from_db.py +11 -23
  10. simtools/applications/derive_trigger_rates.py +91 -0
  11. simtools/applications/plot_simtel_events.py +73 -31
  12. simtools/applications/validate_file_using_schema.py +7 -4
  13. simtools/configuration/commandline_parser.py +17 -11
  14. simtools/data_model/validate_data.py +8 -3
  15. simtools/db/db_handler.py +83 -26
  16. simtools/db/db_model_upload.py +11 -16
  17. simtools/dependencies.py +10 -5
  18. simtools/layout/array_layout_utils.py +37 -5
  19. simtools/model/array_model.py +18 -1
  20. simtools/model/site_model.py +25 -0
  21. simtools/production_configuration/derive_corsika_limits.py +9 -34
  22. simtools/ray_tracing/incident_angles.py +706 -0
  23. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +2 -2
  24. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +1 -1
  25. simtools/schemas/model_parameters/nsb_spectrum.schema.yml +22 -29
  26. simtools/schemas/model_parameters/stars.schema.yml +1 -1
  27. simtools/schemas/production_tables.schema.yml +5 -0
  28. simtools/simtel/simtel_config_writer.py +17 -19
  29. simtools/simtel/simtel_io_event_histograms.py +253 -516
  30. simtools/simtel/simtel_io_event_reader.py +51 -2
  31. simtools/simtel/simtel_io_event_writer.py +31 -11
  32. simtools/simtel/simtel_io_metadata.py +1 -1
  33. simtools/simtel/simtel_table_reader.py +3 -3
  34. simtools/telescope_trigger_rates.py +119 -0
  35. simtools/testing/log_inspector.py +13 -11
  36. simtools/utils/geometry.py +20 -0
  37. simtools/visualization/plot_incident_angles.py +431 -0
  38. simtools/visualization/plot_simtel_event_histograms.py +376 -0
  39. simtools/visualization/visualize.py +1 -3
  40. simtools/applications/calculate_trigger_rate.py +0 -187
  41. simtools/applications/generate_sim_telarray_histograms.py +0 -196
  42. simtools/simtel/simtel_io_histogram.py +0 -623
  43. simtools/simtel/simtel_io_histograms.py +0 -556
  44. {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/WHEEL +0 -0
  45. {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/licenses/LICENSE +0 -0
  46. {gammasimtools-0.19.0.dist-info → gammasimtools-0.20.0.dist-info}/top_level.txt +0 -0
  47. /simtools/visualization/{simtel_event_plots.py → plot_simtel_events.py} +0 -0
@@ -282,11 +282,7 @@ def get_array_layouts_from_db(
282
282
  """
283
283
  layout_names = []
284
284
  if layout_name:
285
- layout_names.append(
286
- layout_name[0]
287
- if isinstance(layout_name, list) and len(layout_name) == 1
288
- else layout_name
289
- )
285
+ layout_names = gen.ensure_iterable(layout_name)
290
286
  else:
291
287
  site_model = SiteModel(site=site, model_version=model_version, mongo_db_config=db_config)
292
288
  layout_names = site_model.get_list_of_array_layouts()
@@ -394,3 +390,39 @@ def _get_array_layout_dict(
394
390
  coordinate_system=coordinate_system
395
391
  ),
396
392
  }
393
+
394
+
395
+ def get_array_elements_from_db_for_layouts(layouts, site, model_version, db_config):
396
+ """
397
+ Get list of array elements from the database for given list of layout names.
398
+
399
+ Structure of the returned dictionary::
400
+
401
+ {
402
+ "layout_name_1": [telescope_id_1, telescope_id_2, ...],
403
+ "layout_name_2": [telescope_id_3, telescope_id_4, ...],
404
+ ...
405
+ }
406
+
407
+ Parameters
408
+ ----------
409
+ layouts : list[str]
410
+ List of layout names to read. If "all", read all available layouts.
411
+ site : str
412
+ Site name for the array layouts.
413
+ model_version : str
414
+ Model version for the array layouts.
415
+ db_config : dict
416
+ Database configuration dictionary.
417
+
418
+ Returns
419
+ -------
420
+ dict
421
+ Dictionary mapping layout names to telescope IDs.
422
+ """
423
+ site_model = SiteModel(site=site, model_version=model_version, mongo_db_config=db_config)
424
+ layout_names = site_model.get_list_of_array_layouts() if layouts == ["all"] else layouts
425
+ layout_dict = {}
426
+ for layout_name in layout_names:
427
+ layout_dict[layout_name] = site_model.get_array_elements_for_layout(layout_name)
428
+ return layout_dict
@@ -272,7 +272,7 @@ class ArrayModel:
272
272
  config_file_path=self.config_file_path,
273
273
  telescope_model=self.telescope_model,
274
274
  site_model=self.site_model,
275
- sim_telarray_seeds=self.sim_telarray_seeds,
275
+ additional_metadata=self._get_additional_simtel_metadata(),
276
276
  )
277
277
  self._array_model_file_exported = True
278
278
 
@@ -484,3 +484,20 @@ class ArrayModel:
484
484
 
485
485
  table.sort("telescope_name")
486
486
  return table
487
+
488
+ def _get_additional_simtel_metadata(self):
489
+ """
490
+ Collect additional metadata to be included in sim_telarray output.
491
+
492
+ Returns
493
+ -------
494
+ dict
495
+ Dictionary with additional metadata.
496
+ """
497
+ metadata = {}
498
+ if self.sim_telarray_seeds is not None:
499
+ metadata.update(self.sim_telarray_seeds)
500
+
501
+ metadata["nsb_integrated_flux"] = self.site_model.get_nsb_integrated_flux()
502
+
503
+ return metadata
@@ -4,6 +4,9 @@
4
4
  import logging
5
5
  from pathlib import Path
6
6
 
7
+ import numpy as np
8
+ from astropy import units as u
9
+
7
10
  from simtools.model.model_parameter import ModelParameter
8
11
 
9
12
  __all__ = ["SiteModel"]
@@ -160,3 +163,25 @@ class SiteModel(ModelParameter):
160
163
  },
161
164
  dest=model_directory,
162
165
  )
166
+
167
+ def get_nsb_integrated_flux(self, wavelength_min=300 * u.nm, wavelength_max=650 * u.nm):
168
+ """
169
+ Get the integrated flux for the NSB (Night Sky Background) model.
170
+
171
+ Returns
172
+ -------
173
+ float
174
+ Integrated flux value.
175
+ """
176
+ table = self.db.get_ecsv_file_as_astropy_table(
177
+ file_name=self.get_parameter_value("nsb_spectrum")
178
+ )
179
+ table.sort("wavelength")
180
+ wl = table["wavelength"].quantity.to(u.nm)
181
+ rate = table["differential photon rate"].quantity.to(1 / (u.nm * u.cm**2 * u.ns * u.sr))
182
+ mask = (wl >= wavelength_min) & (wl <= wavelength_max)
183
+ integral_cm2 = np.trapezoid(rate[mask], wl[mask])
184
+ self._logger.debug(
185
+ f"NSB integral between {wavelength_min} and {wavelength_max}: {integral_cm2}"
186
+ )
187
+ return integral_cm2.value
@@ -9,8 +9,9 @@ from astropy.table import Column, Table
9
9
 
10
10
  from simtools.data_model.metadata_collector import MetadataCollector
11
11
  from simtools.io import ascii_handler, io_handler
12
- from simtools.model.site_model import SiteModel
12
+ from simtools.layout.array_layout_utils import get_array_elements_from_db_for_layouts
13
13
  from simtools.simtel.simtel_io_event_histograms import SimtelIOEventHistograms
14
+ from simtools.visualization import plot_simtel_event_histograms
14
15
 
15
16
  _logger = logging.getLogger(__name__)
16
17
 
@@ -27,7 +28,7 @@ def generate_corsika_limits_grid(args_dict, db_config=None):
27
28
  Database configuration dictionary.
28
29
  """
29
30
  if args_dict.get("array_layout_name"):
30
- telescope_configs = _read_array_layouts_from_db(
31
+ telescope_configs = get_array_elements_from_db_for_layouts(
31
32
  args_dict["array_layout_name"],
32
33
  args_dict.get("site"),
33
34
  args_dict.get("model_version"),
@@ -92,9 +93,11 @@ def _process_file(file_path, array_name, telescope_ids, loss_fraction, plot_hist
92
93
  }
93
94
 
94
95
  if plot_histograms:
95
- histograms.plot_data(
96
+ plot_simtel_event_histograms.plot(
97
+ histograms.histograms,
96
98
  output_path=io_handler.IOHandler().get_output_directory(),
97
99
  limits=limits,
100
+ array_name=array_name,
98
101
  )
99
102
 
100
103
  return limits
@@ -213,34 +216,6 @@ def _create_table_columns(cols, columns, units):
213
216
  return table_cols
214
217
 
215
218
 
216
- def _read_array_layouts_from_db(layouts, site, model_version, db_config):
217
- """
218
- Read array layouts from the database.
219
-
220
- Parameters
221
- ----------
222
- layouts : list[str]
223
- List of layout names to read. If "all", read all available layouts.
224
- site : str
225
- Site name for the array layouts.
226
- model_version : str
227
- Model version for the array layouts.
228
- db_config : dict
229
- Database configuration dictionary.
230
-
231
- Returns
232
- -------
233
- dict
234
- Dictionary mapping layout names to telescope IDs.
235
- """
236
- site_model = SiteModel(site=site, model_version=model_version, mongo_db_config=db_config)
237
- layout_names = site_model.get_list_of_array_layouts() if layouts == ["all"] else layouts
238
- layout_dict = {}
239
- for layout_name in layout_names:
240
- layout_dict[layout_name] = site_model.get_array_elements_for_layout(layout_name)
241
- return layout_dict
242
-
243
-
244
219
  def _compute_limits(hist, bin_edges, loss_fraction, limit_type="lower"):
245
220
  """
246
221
  Compute the limits based on the loss fraction.
@@ -294,7 +269,7 @@ def compute_lower_energy_limit(histograms, loss_fraction):
294
269
  """
295
270
  energy_min = (
296
271
  _compute_limits(
297
- histograms.histograms.get("energy"),
272
+ histograms.histograms["energy"]["histogram"],
298
273
  histograms.energy_bins,
299
274
  loss_fraction,
300
275
  limit_type="lower",
@@ -336,7 +311,7 @@ def compute_upper_radius_limit(histograms, loss_fraction):
336
311
  """
337
312
  radius_limit = (
338
313
  _compute_limits(
339
- histograms.histograms.get("core_distance"),
314
+ histograms.histograms["core_distance"]["histogram"],
340
315
  histograms.core_distance_bins,
341
316
  loss_fraction,
342
317
  limit_type="upper",
@@ -374,7 +349,7 @@ def compute_viewcone(histograms, loss_fraction):
374
349
  """
375
350
  viewcone_limit = (
376
351
  _compute_limits(
377
- histograms.histograms.get("angular_distance"),
352
+ histograms.histograms["angular_distance"]["histogram"],
378
353
  histograms.view_cone_bins,
379
354
  loss_fraction,
380
355
  limit_type="upper",