gammasimtools 0.10.0__py3-none-any.whl → 0.12.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 (84) hide show
  1. {gammasimtools-0.10.0.dist-info → gammasimtools-0.12.0.dist-info}/METADATA +3 -1
  2. {gammasimtools-0.10.0.dist-info → gammasimtools-0.12.0.dist-info}/RECORD +84 -77
  3. {gammasimtools-0.10.0.dist-info → gammasimtools-0.12.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.10.0.dist-info → gammasimtools-0.12.0.dist-info}/entry_points.txt +4 -0
  5. simtools/_version.py +9 -4
  6. simtools/applications/convert_all_model_parameters_from_simtel.py +0 -1
  7. simtools/applications/convert_model_parameter_from_simtel.py +0 -1
  8. simtools/applications/db_add_file_to_db.py +0 -1
  9. simtools/applications/db_get_parameter_from_db.py +7 -28
  10. simtools/applications/derive_mirror_rnda.py +1 -2
  11. simtools/applications/derive_psf_parameters.py +1 -0
  12. simtools/applications/docs_produce_array_element_report.py +71 -0
  13. simtools/applications/docs_produce_model_parameter_reports.py +63 -0
  14. simtools/applications/generate_corsika_histograms.py +2 -2
  15. simtools/applications/generate_regular_arrays.py +4 -2
  16. simtools/applications/production_derive_limits.py +95 -0
  17. simtools/applications/production_generate_simulation_config.py +15 -29
  18. simtools/applications/production_scale_events.py +2 -7
  19. simtools/applications/run_application.py +165 -0
  20. simtools/applications/simulate_light_emission.py +0 -4
  21. simtools/applications/submit_model_parameter_from_external.py +11 -6
  22. simtools/applications/validate_file_using_schema.py +3 -3
  23. simtools/configuration/commandline_parser.py +30 -1
  24. simtools/configuration/configurator.py +8 -10
  25. simtools/corsika/corsika_config.py +11 -10
  26. simtools/corsika/corsika_histograms.py +4 -6
  27. simtools/corsika/corsika_histograms_visualize.py +2 -4
  28. simtools/data_model/metadata_collector.py +18 -9
  29. simtools/data_model/model_data_writer.py +67 -15
  30. simtools/data_model/schema.py +10 -3
  31. simtools/data_model/validate_data.py +70 -24
  32. simtools/db/db_handler.py +46 -14
  33. simtools/dependencies.py +112 -0
  34. simtools/layout/array_layout.py +5 -4
  35. simtools/model/model_parameter.py +35 -2
  36. simtools/production_configuration/calculate_statistical_errors_grid_point.py +5 -6
  37. simtools/production_configuration/event_scaler.py +3 -19
  38. simtools/production_configuration/generate_simulation_config.py +4 -12
  39. simtools/production_configuration/interpolation_handler.py +2 -5
  40. simtools/production_configuration/limits_calculation.py +202 -0
  41. simtools/reporting/docs_read_parameters.py +310 -0
  42. simtools/runners/corsika_simtel_runner.py +1 -3
  43. simtools/schemas/{integration_tests_config.metaschema.yml → application_workflow.metaschema.yml} +51 -27
  44. simtools/schemas/array_elements.yml +8 -0
  45. simtools/schemas/model_parameter.metaschema.yml +96 -0
  46. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +2 -1
  47. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +1 -1
  48. simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +2 -0
  49. simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +2 -0
  50. simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +2 -0
  51. simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +2 -0
  52. simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +2 -0
  53. simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +2 -0
  54. simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +2 -0
  55. simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +2 -0
  56. simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +2 -0
  57. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +1 -1
  58. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +1 -1
  59. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +1 -1
  60. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +1 -1
  61. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +1 -1
  62. simtools/schemas/model_parameters/min_photons.schema.yml +1 -1
  63. simtools/schemas/model_parameters/random_generator.schema.yml +1 -1
  64. simtools/schemas/model_parameters/sampled_output.schema.yml +1 -1
  65. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +1 -1
  66. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +1 -1
  67. simtools/schemas/model_parameters/tailcut_scale.schema.yml +1 -1
  68. simtools/schemas/production_tables.schema.yml +1 -1
  69. simtools/simtel/simtel_config_reader.py +1 -2
  70. simtools/simtel/simtel_config_writer.py +1 -2
  71. simtools/simtel/simtel_io_histogram.py +0 -1
  72. simtools/simtel/simtel_io_histograms.py +2 -4
  73. simtools/simtel/simulator_camera_efficiency.py +1 -3
  74. simtools/simtel/simulator_light_emission.py +2 -5
  75. simtools/simtel/simulator_ray_tracing.py +1 -3
  76. simtools/testing/configuration.py +2 -1
  77. simtools/testing/validate_output.py +23 -13
  78. simtools/utils/general.py +12 -2
  79. simtools/utils/names.py +290 -152
  80. simtools/utils/value_conversion.py +20 -14
  81. simtools/version.py +2 -2
  82. simtools/visualization/legend_handlers.py +2 -0
  83. {gammasimtools-0.10.0.dist-info → gammasimtools-0.12.0.dist-info}/LICENSE +0 -0
  84. {gammasimtools-0.10.0.dist-info → gammasimtools-0.12.0.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,7 @@ data:
15
15
  allowed_range:
16
16
  min: 100000
17
17
  instrument:
18
- class: Camera
18
+ class: configuration_sim_telarray
19
19
  type:
20
20
  - LSTN
21
21
  - LSTS
@@ -15,7 +15,7 @@ data:
15
15
  allowed_range:
16
16
  min: 100000
17
17
  instrument:
18
- class: Camera
18
+ class: configuration_sim_telarray
19
19
  type:
20
20
  - LSTN
21
21
  - LSTS
@@ -3,7 +3,7 @@
3
3
  title: Schema for lightguide_efficiency_vs_incidence_angle model parameter
4
4
  version: 0.1.0
5
5
  meta_schema: simpipe-schema
6
- meta_schema_url: https://raw.githubusercontent.com/gammasim/simtools/main/src/simtools/schemas/data.metaschema.yml
6
+ meta_schema_url: https://raw.githubusercontent.com/gammasim/simtools/main/src/simtools/schemas/model_parameter_and_data_schema.metaschema.yml
7
7
  meta_schema_version: 0.1.0
8
8
  name: lightguide_efficiency_vs_incidence_angle
9
9
  developer_note: |-
@@ -3,7 +3,7 @@
3
3
  title: Schema for lightguide_efficiency_vs_wavelength model parameter
4
4
  version: 0.1.0
5
5
  meta_schema: simpipe-schema
6
- meta_schema_url: https://raw.githubusercontent.com/gammasim/simtools/main/src/simtools/schemas/data.metaschema.yml
6
+ meta_schema_url: https://raw.githubusercontent.com/gammasim/simtools/main/src/simtools/schemas/model_parameter_and_data_schema.metaschema.yml
7
7
  meta_schema_version: 0.1.0
8
8
  name: lightguide_efficiency_vs_wavelength
9
9
  developer_note: |-
@@ -16,7 +16,7 @@ data:
16
16
  unit: dimensionless
17
17
  default: -1
18
18
  instrument:
19
- class: Camera
19
+ class: configuration_sim_telarray
20
20
  type:
21
21
  - LSTN
22
22
  - LSTS
@@ -13,7 +13,7 @@ data:
13
13
  unit: dimensionless
14
14
  default: -1
15
15
  instrument:
16
- class: Camera
16
+ class: configuration_sim_telarray
17
17
  type:
18
18
  - LSTN
19
19
  - LSTS
@@ -17,7 +17,7 @@ data:
17
17
  - type: string
18
18
  default: "Ranlux"
19
19
  instrument:
20
- class: Camera
20
+ class: configuration_sim_telarray
21
21
  type:
22
22
  - LSTN
23
23
  - LSTS
@@ -12,7 +12,7 @@ data:
12
12
  - type: boolean
13
13
  default: true
14
14
  instrument:
15
- class: Camera
15
+ class: configuration_sim_telarray
16
16
  type:
17
17
  - LSTN
18
18
  - LSTS
@@ -15,7 +15,7 @@ data:
15
15
  - type: boolean
16
16
  default: false
17
17
  instrument:
18
- class: Camera
18
+ class: configuration_sim_telarray
19
19
  type:
20
20
  - LSTN
21
21
  - LSTS
@@ -22,7 +22,7 @@ data:
22
22
  min: 0
23
23
  max: 10000
24
24
  instrument:
25
- class: Camera
25
+ class: configuration_sim_telarray
26
26
  type:
27
27
  - LSTN
28
28
  - LSTS
@@ -19,7 +19,7 @@ data:
19
19
  min: 0.0
20
20
  max: 10.0
21
21
  instrument:
22
- class: Camera
22
+ class: configuration_sim_telarray
23
23
  type:
24
24
  - LSTN
25
25
  - LSTS
@@ -29,7 +29,7 @@ definitions:
29
29
  pattern: '^\d+\.\d+\.\d+$'
30
30
  propertyNames:
31
31
  description: Allowed parameter name patterns.
32
- pattern: '^([A-Za-z](ST|LL)[N,S,x]-\d{2,3}|[A-Za-z](ST|LL)[N,S,x]-design|OBS-(North|South)|Dummy-Telescope)$'
32
+ pattern: '^([A-Za-z](ST|LL)[N,S,x]-\d{2,3}|[A-Za-z](ST|LL)[N,S,x]-(design|FlashCam|NectarCam)|OBS-(North|South)|Dummy-Telescope)$'
33
33
  design_model:
34
34
  type: object
35
35
  description: Design models.
@@ -153,8 +153,7 @@ class SimtelConfigReader:
153
153
 
154
154
  """
155
155
  self._logger.debug(
156
- f"Reading simtel config file {simtel_config_file} "
157
- f"for parameter {self.parameter_name}"
156
+ f"Reading simtel config file {simtel_config_file} for parameter {self.parameter_name}"
158
157
  )
159
158
  matching_lines = {}
160
159
  try:
@@ -72,8 +72,7 @@ class SimtelConfigWriter:
72
72
 
73
73
  file.write("#ifdef TELESCOPE\n")
74
74
  file.write(
75
- f" echo Configuration for {self._telescope_model_name}"
76
- " - TELESCOPE $(TELESCOPE)\n"
75
+ f" echo Configuration for {self._telescope_model_name} - TELESCOPE $(TELESCOPE)\n"
77
76
  )
78
77
  file.write("#endif\n\n")
79
78
 
@@ -419,7 +419,6 @@ class SimtelIOHistogram:
419
419
  return {
420
420
  "simtel_array_file": self.histogram_file,
421
421
  "simulation_input": self.print_info(mode="silent"),
422
- # pylint: disable=E1101
423
422
  "system_trigger_rate (Hz)": self.trigger_rate.value,
424
423
  }
425
424
 
@@ -219,8 +219,8 @@ class SimtelIOHistograms:
219
219
  )
220
220
 
221
221
  stacked_num_simulated_events, stacked_num_triggered_events = self.get_stacked_num_events()
222
- logging.info("Total number of simulated events: " f"{stacked_num_simulated_events} events")
223
- logging.info("Total number of triggered events: " f"{stacked_num_triggered_events} events")
222
+ logging.info(f"Total number of simulated events: {stacked_num_simulated_events} events")
223
+ logging.info(f"Total number of triggered events: {stacked_num_triggered_events} events")
224
224
  obs_time = simtel_hist_instance.estimate_observation_time(stacked_num_simulated_events)
225
225
  logging.info(
226
226
  "Estimated equivalent observation time corresponding to the number of"
@@ -239,9 +239,7 @@ class SimtelIOHistograms:
239
239
  )
240
240
  logging.info(
241
241
  f"System trigger event rate for stacked files: "
242
- # pylint: disable=E1101
243
242
  f"{triggered_event_rate.value:.4e} \u00b1 "
244
- # pylint: disable=E1101
245
243
  f"{triggered_event_rate_uncertainty.value:.4e} Hz"
246
244
  )
247
245
  return (
@@ -72,9 +72,7 @@ class SimulatorCameraEfficiency(SimtelRunner):
72
72
  / Path(self._telescope_model.get_parameter_value("nsb_reference_spectrum")).name
73
73
  )
74
74
 
75
- def _make_run_command(
76
- self, run_number=None, input_file=None
77
- ): # pylint: disable=unused-argument
75
+ def _make_run_command(self, run_number=None, input_file=None): # pylint: disable=unused-argument
78
76
  """Prepare the command used to run testeff."""
79
77
  self._logger.debug("Preparing the command to run testeff")
80
78
 
@@ -234,7 +234,6 @@ class SimulatorLightEmission(SimtelRunner):
234
234
  command += f"/{self.le_application[0]}"
235
235
 
236
236
  if self.light_source_type == "led":
237
-
238
237
  if self.le_application[1] == "variable":
239
238
  command += f" -x {self.default_le_config['x_pos']['default'].to(u.cm).value}"
240
239
  command += f" -y {self.default_le_config['y_pos']['default'].to(u.cm).value}"
@@ -245,7 +244,6 @@ class SimulatorLightEmission(SimtelRunner):
245
244
  command += f" -n {self.photons_per_run}"
246
245
 
247
246
  elif self.le_application[1] == "layout":
248
-
249
247
  x_origin = x_cal - x_tel
250
248
  y_origin = y_cal - y_tel
251
249
  z_origin = z_cal - z_tel
@@ -291,7 +289,7 @@ class SimulatorLightEmission(SimtelRunner):
291
289
 
292
290
  command += f" --telescope-theta {angle_theta}"
293
291
  command += f" --telescope-phi {angle_phi}"
294
- command += f" --laser-theta {90-angles[2]}"
292
+ command += f" --laser-theta {90 - angles[2]}"
295
293
  command += f" --laser-phi {angles[3]}" # convention north (x) towards east (-y)
296
294
  command += f" --atmosphere {_model_directory}/"
297
295
  command += f"{self._telescope_model.get_parameter_value('atmospheric_profile')}"
@@ -352,8 +350,7 @@ class SimulatorLightEmission(SimtelRunner):
352
350
  )
353
351
  command += super().get_config_option(
354
352
  "output_file",
355
- f"{self.output_directory}/"
356
- f"{self.le_application[0]}_{self.le_application[1]}.simtel.gz",
353
+ f"{self.output_directory}/{self.le_application[0]}_{self.le_application[1]}.simtel.gz",
357
354
  )
358
355
  command += super().get_config_option(
359
356
  "histogram_file",
@@ -136,9 +136,7 @@ class SimulatorRayTracing(SimtelRunner):
136
136
  self._logger.debug("For single mirror mode, need to prepare the single pixel camera.")
137
137
  self._write_out_single_pixel_camera_file()
138
138
 
139
- def _make_run_command(
140
- self, run_number=None, input_file=None
141
- ): # pylint: disable=unused-argument
139
+ def _make_run_command(self, run_number=None, input_file=None): # pylint: disable=unused-argument
142
140
  """Generate simtel_array run command."""
143
141
  if self.config.single_mirror_mode:
144
142
  # Note: no mirror length defined for dual-mirror telescopes
@@ -71,7 +71,8 @@ def _read_configs_from_files(config_files):
71
71
  _dict = gen.remove_substring_recursively_from_dict(
72
72
  gen.collect_data_from_file(file_name=config_file), substring="\n"
73
73
  )
74
- configs.append(_dict.get("CTA_SIMPIPE", None))
74
+ for application in _dict.get("CTA_SIMPIPE", {}).get("APPLICATIONS", []):
75
+ configs.append(application)
75
76
  return configs
76
77
 
77
78
 
@@ -37,17 +37,7 @@ def validate_application_output(config, from_command_line=None, from_config_file
37
37
  _logger.info(f"Testing application output: {integration_test}")
38
38
 
39
39
  if from_command_line == from_config_file:
40
- if "REFERENCE_OUTPUT_FILE" in integration_test:
41
- _validate_reference_output_file(config, integration_test)
42
-
43
- if "TEST_OUTPUT_FILES" in integration_test:
44
- _validate_output_path_and_file(config, integration_test["TEST_OUTPUT_FILES"])
45
-
46
- if "OUTPUT_FILE" in integration_test:
47
- _validate_output_path_and_file(
48
- config,
49
- [{"PATH_DESCRIPTOR": "OUTPUT_PATH", "FILE": integration_test["OUTPUT_FILE"]}],
50
- )
40
+ _validate_output_files(config, integration_test)
51
41
 
52
42
  if "FILE_TYPE" in integration_test:
53
43
  assert assertions.assert_file_type(
@@ -59,6 +49,19 @@ def validate_application_output(config, from_command_line=None, from_config_file
59
49
  _test_simtel_cfg_files(config, integration_test, from_command_line, from_config_file)
60
50
 
61
51
 
52
+ def _validate_output_files(config, integration_test):
53
+ """Validate output files."""
54
+ if "REFERENCE_OUTPUT_FILE" in integration_test:
55
+ _validate_reference_output_file(config, integration_test)
56
+ if "TEST_OUTPUT_FILES" in integration_test:
57
+ _validate_output_path_and_file(config, integration_test["TEST_OUTPUT_FILES"])
58
+ if "OUTPUT_FILE" in integration_test:
59
+ _validate_output_path_and_file(
60
+ config,
61
+ [{"PATH_DESCRIPTOR": "OUTPUT_PATH", "FILE": integration_test["OUTPUT_FILE"]}],
62
+ )
63
+
64
+
62
65
  def _test_simtel_cfg_files(config, integration_test, from_command_line, from_config_file):
63
66
  """Test simtel cfg files."""
64
67
  test_simtel_cfg_file = integration_test.get("TEST_SIMTEL_CFG_FILES", {}).get(
@@ -141,6 +144,7 @@ def compare_json_or_yaml_files(file1, file2, tolerance=1.0e-2):
141
144
  Compare two json or yaml files.
142
145
 
143
146
  Take into account float comparison for sim_telarray string-embedded floats.
147
+ Allow differences in 'schema_version' field.
144
148
 
145
149
  Parameters
146
150
  ----------
@@ -159,6 +163,8 @@ def compare_json_or_yaml_files(file1, file2, tolerance=1.0e-2):
159
163
  """
160
164
  data1 = gen.collect_data_from_file(file1)
161
165
  data2 = gen.collect_data_from_file(file2)
166
+ data1.pop("schema_version", None)
167
+ data2.pop("schema_version", None)
162
168
 
163
169
  _logger.debug(f"Comparing json/yaml files: {file1} and {file2}")
164
170
 
@@ -181,7 +187,7 @@ def compare_json_or_yaml_files(file1, file2, tolerance=1.0e-2):
181
187
  return _comparison
182
188
 
183
189
 
184
- def _compare_value_from_parameter_dict(data1, data2, tolerance):
190
+ def _compare_value_from_parameter_dict(data1, data2, tolerance=1.0e-5):
185
191
  """Compare value fields given in different formats."""
186
192
 
187
193
  def _as_list(value):
@@ -193,7 +199,11 @@ def _compare_value_from_parameter_dict(data1, data2, tolerance):
193
199
 
194
200
  _logger.info(f"Comparing values: {data1} and {data2} (tolerance: {tolerance})")
195
201
 
196
- return np.allclose(_as_list(data1), _as_list(data2), rtol=tolerance)
202
+ _as_list_1 = _as_list(data1)
203
+ _as_list_2 = _as_list(data2)
204
+ if isinstance(_as_list_1, str):
205
+ return _as_list_1 == _as_list_2
206
+ return np.allclose(_as_list_1, _as_list_2, rtol=tolerance)
197
207
 
198
208
 
199
209
  def compare_ecsv_files(file1, file2, tolerance=1.0e-5, test_columns=None):
simtools/utils/general.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """General functions useful across different parts of the code."""
2
2
 
3
3
  import copy
4
+ import datetime
4
5
  import json
5
6
  import logging
6
7
  import os
@@ -743,7 +744,7 @@ def convert_list_to_string(data, comma_separated=False, shorten_list=False, coll
743
744
  return " ".join(str(item) for item in data)
744
745
 
745
746
 
746
- def convert_string_to_list(data_string, is_float=True):
747
+ def convert_string_to_list(data_string, is_float=True, force_comma_separation=False):
747
748
  """
748
749
  Convert string (as used e.g. in sim_telarray) to list.
749
750
 
@@ -753,6 +754,10 @@ def convert_string_to_list(data_string, is_float=True):
753
754
  ----------
754
755
  data_string: object
755
756
  String to be converted
757
+ is_float: bool
758
+ If True, convert to float, otherwise to int.
759
+ force_comma_separation: bool
760
+ If True, force comma separation.
756
761
 
757
762
  Returns
758
763
  -------
@@ -770,7 +775,7 @@ def convert_string_to_list(data_string, is_float=True):
770
775
  if "," in data_string:
771
776
  result = data_string.split(",")
772
777
  return [item.strip() for item in result]
773
- if " " in data_string:
778
+ if " " in data_string and not force_comma_separation:
774
779
  return data_string.split()
775
780
  return data_string
776
781
 
@@ -922,3 +927,8 @@ def get_list_of_files_from_command_line(file_names, suffix_list):
922
927
  _logger.error(f"{one_file} is not a file.")
923
928
  raise FileNotFoundError from exc
924
929
  return _files
930
+
931
+
932
+ def now_date_time_in_isoformat():
933
+ """Return date and time in isoformat and second accuracy."""
934
+ return datetime.datetime.now(datetime.UTC).isoformat(timespec="seconds")