gammasimtools 0.25.0__py3-none-any.whl → 0.26.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 (125) hide show
  1. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/METADATA +2 -1
  2. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/RECORD +122 -121
  3. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/entry_points.txt +2 -1
  4. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/licenses/LICENSE +1 -1
  5. simtools/_version.py +2 -2
  6. simtools/application_control.py +35 -7
  7. simtools/applications/calculate_incident_angles.py +0 -2
  8. simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -2
  9. simtools/applications/db_add_file_to_db.py +1 -1
  10. simtools/applications/db_add_simulation_model_from_repository_to_db.py +1 -1
  11. simtools/applications/db_add_value_from_json_to_db.py +1 -1
  12. simtools/applications/db_generate_compound_indexes.py +1 -1
  13. simtools/applications/db_get_array_layouts_from_db.py +2 -6
  14. simtools/applications/db_get_file_from_db.py +1 -1
  15. simtools/applications/db_get_parameter_from_db.py +1 -1
  16. simtools/applications/db_inspect_databases.py +1 -1
  17. simtools/applications/db_upload_model_repository.py +1 -1
  18. simtools/applications/derive_ctao_array_layouts.py +1 -2
  19. simtools/applications/derive_mirror_rnda.py +1 -3
  20. simtools/applications/derive_psf_parameters.py +0 -1
  21. simtools/applications/derive_pulse_shape_parameters.py +0 -1
  22. simtools/applications/derive_trigger_rates.py +1 -1
  23. simtools/applications/docs_produce_array_element_report.py +2 -8
  24. simtools/applications/docs_produce_calibration_reports.py +1 -3
  25. simtools/applications/docs_produce_model_parameter_reports.py +0 -2
  26. simtools/applications/docs_produce_simulation_configuration_report.py +1 -3
  27. simtools/applications/generate_array_config.py +0 -1
  28. simtools/applications/generate_corsika_histograms.py +48 -235
  29. simtools/applications/generate_regular_arrays.py +5 -35
  30. simtools/applications/generate_simtel_event_data.py +2 -2
  31. simtools/applications/maintain_simulation_model_add_production.py +2 -2
  32. simtools/applications/maintain_simulation_model_write_array_element_positions.py +87 -0
  33. simtools/applications/plot_array_layout.py +5 -111
  34. simtools/applications/plot_simulated_event_distributions.py +57 -0
  35. simtools/applications/plot_tabular_data.py +0 -1
  36. simtools/applications/plot_tabular_data_for_model_parameter.py +1 -6
  37. simtools/applications/production_derive_corsika_limits.py +1 -1
  38. simtools/applications/production_generate_grid.py +0 -1
  39. simtools/applications/run_application.py +1 -1
  40. simtools/applications/simulate_flasher.py +0 -2
  41. simtools/applications/simulate_illuminator.py +0 -1
  42. simtools/applications/simulate_pedestals.py +1 -5
  43. simtools/applications/simulate_prod.py +1 -5
  44. simtools/applications/simulate_prod_htcondor_generator.py +1 -1
  45. simtools/applications/submit_array_layouts.py +2 -4
  46. simtools/applications/submit_model_parameter_from_external.py +1 -3
  47. simtools/applications/validate_camera_efficiency.py +0 -1
  48. simtools/applications/validate_camera_fov.py +0 -1
  49. simtools/applications/validate_cumulative_psf.py +0 -2
  50. simtools/applications/validate_optics.py +0 -13
  51. simtools/camera/camera_efficiency.py +1 -6
  52. simtools/camera/single_photon_electron_spectrum.py +2 -1
  53. simtools/configuration/commandline_parser.py +35 -2
  54. simtools/configuration/configurator.py +6 -11
  55. simtools/corsika/corsika_config.py +16 -21
  56. simtools/corsika/corsika_histograms.py +411 -1735
  57. simtools/corsika/primary_particle.py +1 -1
  58. simtools/data_model/metadata_collector.py +5 -2
  59. simtools/data_model/metadata_model.py +0 -4
  60. simtools/data_model/model_data_writer.py +13 -15
  61. simtools/data_model/validate_data.py +1 -3
  62. simtools/db/db_handler.py +19 -8
  63. simtools/dependencies.py +81 -38
  64. simtools/io/ascii_handler.py +4 -2
  65. simtools/io/table_handler.py +1 -1
  66. simtools/layout/array_layout.py +4 -12
  67. simtools/layout/array_layout_utils.py +226 -57
  68. simtools/model/array_model.py +1 -13
  69. simtools/model/calibration_model.py +0 -4
  70. simtools/model/legacy_model_parameter.py +134 -0
  71. simtools/model/model_parameter.py +24 -13
  72. simtools/model/model_utils.py +1 -6
  73. simtools/model/site_model.py +0 -4
  74. simtools/model/telescope_model.py +6 -11
  75. simtools/production_configuration/derive_corsika_limits.py +6 -11
  76. simtools/production_configuration/interpolation_handler.py +16 -16
  77. simtools/ray_tracing/incident_angles.py +5 -11
  78. simtools/ray_tracing/mirror_panel_psf.py +3 -7
  79. simtools/ray_tracing/psf_analysis.py +18 -19
  80. simtools/ray_tracing/psf_parameter_optimisation.py +0 -1
  81. simtools/ray_tracing/ray_tracing.py +6 -15
  82. simtools/reporting/docs_auto_report_generator.py +8 -13
  83. simtools/reporting/docs_read_parameters.py +2 -8
  84. simtools/runners/corsika_runner.py +5 -9
  85. simtools/runners/corsika_simtel_runner.py +3 -8
  86. simtools/runners/simtel_runner.py +0 -5
  87. simtools/runners/simtools_runner.py +2 -4
  88. simtools/settings.py +154 -0
  89. simtools/{io/eventio_handler.py → sim_events/file_info.py} +3 -3
  90. simtools/{simtel/simtel_io_event_histograms.py → sim_events/histograms.py} +25 -15
  91. simtools/{simtel/simtel_io_event_reader.py → sim_events/reader.py} +20 -17
  92. simtools/{simtel/simtel_io_event_writer.py → sim_events/writer.py} +84 -25
  93. simtools/simtel/pulse_shapes.py +7 -2
  94. simtools/simtel/simtel_config_writer.py +79 -36
  95. simtools/simtel/simtel_table_reader.py +6 -4
  96. simtools/simtel/simulator_array.py +4 -11
  97. simtools/simtel/simulator_camera_efficiency.py +4 -6
  98. simtools/simtel/simulator_light_emission.py +69 -24
  99. simtools/simtel/simulator_ray_tracing.py +4 -10
  100. simtools/simulator.py +7 -14
  101. simtools/telescope_trigger_rates.py +3 -4
  102. simtools/testing/assertions.py +84 -33
  103. simtools/testing/configuration.py +1 -2
  104. simtools/testing/helpers.py +2 -3
  105. simtools/testing/log_inspector.py +1 -0
  106. simtools/testing/sim_telarray_metadata.py +1 -1
  107. simtools/testing/validate_output.py +34 -23
  108. simtools/utils/general.py +37 -0
  109. simtools/utils/geometry.py +0 -77
  110. simtools/utils/names.py +5 -5
  111. simtools/visualization/legend_handlers.py +7 -6
  112. simtools/visualization/plot_array_layout.py +91 -16
  113. simtools/visualization/plot_corsika_histograms.py +143 -605
  114. simtools/visualization/plot_mirrors.py +1 -4
  115. simtools/visualization/plot_pixels.py +2 -4
  116. simtools/visualization/plot_psf.py +0 -1
  117. simtools/visualization/plot_simtel_event_histograms.py +4 -4
  118. simtools/visualization/plot_simtel_events.py +6 -11
  119. simtools/visualization/plot_tables.py +8 -19
  120. simtools/visualization/visualize.py +22 -2
  121. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +0 -160
  122. simtools/applications/print_version.py +0 -53
  123. simtools/io/hdf5_handler.py +0 -139
  124. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/WHEEL +0 -0
  125. {gammasimtools-0.25.0.dist-info → gammasimtools-0.26.0.dist-info}/top_level.txt +0 -0
@@ -141,14 +141,10 @@ Plot layout with some telescopes grayed out and others highlighted:
141
141
  --legend_location "upper right"
142
142
  """
143
143
 
144
- import matplotlib as mpl
145
- import matplotlib.pyplot as plt
146
-
147
144
  import simtools.layout.array_layout_utils as layout_utils
148
145
  from simtools.application_control import get_application_label, startup_application
149
146
  from simtools.configuration import configurator
150
- from simtools.visualization import visualize
151
- from simtools.visualization.plot_array_layout import plot_array_layout
147
+ from simtools.visualization.plot_array_layout import plot_array_layouts
152
148
 
153
149
 
154
150
  def _parse():
@@ -278,116 +274,14 @@ def _parse():
278
274
  )
279
275
 
280
276
 
281
- def read_layouts(args_dict, db_config, logger):
282
- """
283
- Read array layouts from the database or parameter file.
284
-
285
- Parameters
286
- ----------
287
- args_dict : dict
288
- Dictionary with command line arguments.
289
- db_config : dict
290
- Database configuration.
291
- logger : logging.app_context.logger
292
- app_context.logger instance.
293
-
294
- Returns
295
- -------
296
- list
297
- List of array layouts.
298
- """
299
- if args_dict["array_layout_name"] is not None or args_dict["plot_all_layouts"]:
300
- logger.info("Plotting array from DB using layout array name(s).")
301
- layouts = layout_utils.get_array_layouts_from_db(
302
- args_dict["array_layout_name"],
303
- args_dict["site"],
304
- args_dict["model_version"],
305
- db_config,
306
- args_dict["coordinate_system"],
307
- )
308
- if isinstance(layouts, list):
309
- return layouts
310
- return [layouts]
311
-
312
- if args_dict["array_layout_parameter_file"] is not None:
313
- logger.info("Plotting array from parameter file(s).")
314
- return layout_utils.get_array_layouts_from_parameter_file(
315
- args_dict["array_layout_parameter_file"],
316
- args_dict["model_version"],
317
- db_config,
318
- args_dict["coordinate_system"],
319
- )
320
-
321
- if args_dict["array_layout_file"] is not None:
322
- logger.info("Plotting array from telescope table file(s).")
323
- return layout_utils.get_array_layouts_from_file(args_dict["array_layout_file"])
324
-
325
- if args_dict["array_element_list"] is not None:
326
- logger.info("Plotting array from list of array elements.")
327
- return layout_utils.get_array_layouts_using_telescope_lists_from_db(
328
- [args_dict["array_element_list"]],
329
- args_dict["site"],
330
- args_dict["model_version"],
331
- db_config,
332
- args_dict["coordinate_system"],
333
- )
334
-
335
- return []
336
-
337
-
338
277
  def main():
339
278
  """Plot array layout application."""
340
279
  app_context = startup_application(_parse)
341
280
 
342
- layouts = read_layouts(app_context.args, app_context.db_config, app_context.logger)
343
-
344
- if app_context.args.get("array_layout_name_background"):
345
- background_layout = layout_utils.get_array_layouts_from_db(
346
- app_context.args["array_layout_name_background"],
347
- app_context.args["site"],
348
- app_context.args["model_version"],
349
- app_context.db_config,
350
- app_context.args["coordinate_system"],
351
- )["array_elements"]
352
- else:
353
- background_layout = None
354
-
355
- mpl.use("Agg")
356
- for layout in layouts:
357
- fig_out = plot_array_layout(
358
- telescopes=layout["array_elements"],
359
- show_tel_label=app_context.args["show_labels"],
360
- axes_range=app_context.args["axes_range"],
361
- marker_scaling=app_context.args["marker_scaling"],
362
- background_telescopes=background_layout,
363
- grayed_out_elements=app_context.args["grayed_out_array_elements"],
364
- highlighted_elements=app_context.args["highlighted_array_elements"],
365
- legend_location=app_context.args["legend_location"],
366
- bounds_mode=app_context.args["bounds"],
367
- padding=app_context.args["padding"],
368
- x_lim=tuple(app_context.args["x_lim"]) if app_context.args["x_lim"] else None,
369
- y_lim=tuple(app_context.args["y_lim"]) if app_context.args["y_lim"] else None,
370
- )
371
- site_string = ""
372
- if layout.get("site") is not None:
373
- site_string = f"_{layout['site']}"
374
- elif app_context.args["site"] is not None:
375
- site_string = f"_{app_context.args['site']}"
376
- coordinate_system_string = (
377
- f"_{app_context.args['coordinate_system']}"
378
- if app_context.args["coordinate_system"] not in layout["name"]
379
- else ""
380
- )
381
- plot_file_name = app_context.args["figure_name"] or (
382
- f"array_layout_{layout['name']}{site_string}{coordinate_system_string}"
383
- )
384
-
385
- visualize.save_figure(
386
- fig_out,
387
- app_context.io_handler.get_output_directory() / plot_file_name,
388
- dpi=400,
389
- )
390
- plt.close()
281
+ layouts, background_layout = layout_utils.read_layouts(app_context.args)
282
+ plot_array_layouts(
283
+ app_context.args, app_context.io_handler.get_output_directory(), layouts, background_layout
284
+ )
391
285
 
392
286
 
393
287
  if __name__ == "__main__":
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/python3
2
+
3
+ r"""
4
+ Plot simulated event distributions for shower and/or triggered event data.
5
+
6
+ Reads reduced event data files and generate histogram plots e.g. for energy or
7
+ core distance distributions.
8
+
9
+ Command line arguments
10
+ ----------------------
11
+ input_file (str, required)
12
+ Input file path.
13
+ output_path (str, required)
14
+ Output directory for the generated plots.
15
+
16
+ Examples
17
+ --------
18
+ Generate plots from a given input file:
19
+
20
+ .. code-block:: console
21
+
22
+ simtools-plot-simulated-event-distributions --input_file path/to/simtel_file.hdf5 \
23
+ --output_path simtools_output/
24
+
25
+
26
+ """
27
+
28
+ from simtools.application_control import get_application_label, startup_application
29
+ from simtools.configuration import configurator
30
+ from simtools.sim_events.histograms import EventDataHistograms
31
+ from simtools.visualization import plot_simtel_event_histograms
32
+
33
+
34
+ def _parse():
35
+ """Parse command line configuration."""
36
+ config = configurator.Configurator(
37
+ label=get_application_label(__file__),
38
+ description="Plot simulated event distributions for shower and/or triggered event data.",
39
+ )
40
+ config.parser.add_argument("--input_file", type=str, required=True, help="Input file path")
41
+ return config.initialize(db_config=False, output=True)
42
+
43
+
44
+ def main():
45
+ """Plot simulated event distributions."""
46
+ app_context = startup_application(_parse)
47
+ app_context.logger.info(f"Loading input file from: {app_context.args['input_file']}")
48
+
49
+ histograms = EventDataHistograms(app_context.args["input_file"])
50
+ histograms.fill()
51
+ plot_simtel_event_histograms.plot(
52
+ histograms.histograms, output_path=app_context.io_handler.get_output_directory()
53
+ )
54
+
55
+
56
+ if __name__ == "__main__":
57
+ main()
@@ -78,7 +78,6 @@ def main():
78
78
  plot_tables.plot(
79
79
  config=plot_config["plot"],
80
80
  output_file=app_context.io_handler.get_output_file(app_context.args["output_file"]),
81
- db_config=app_context.db_config,
82
81
  data_path=app_context.args.get("table_data_path"),
83
82
  )
84
83
 
@@ -81,15 +81,10 @@ def main():
81
81
  telescope=app_context.args.get("telescope"),
82
82
  output_path=app_context.io_handler.get_output_directory(),
83
83
  plot_type=app_context.args["plot_type"],
84
- db_config=app_context.db_config,
85
84
  )
86
85
 
87
86
  for plot_config, output_file in zip(plot_configs, output_files):
88
- plot_tables.plot(
89
- config=plot_config,
90
- output_file=output_file,
91
- db_config=app_context.db_config,
92
- )
87
+ plot_tables.plot(config=plot_config, output_file=output_file)
93
88
  MetadataCollector.dump(app_context.args, output_file=output_file, add_activity_name=True)
94
89
 
95
90
 
@@ -134,7 +134,7 @@ def main():
134
134
  """Derive limits for energy, radial distance, and viewcone."""
135
135
  app_context = startup_application(_parse)
136
136
 
137
- generate_corsika_limits_grid(app_context.args, app_context.db_config)
137
+ generate_corsika_limits_grid(app_context.args)
138
138
 
139
139
 
140
140
  if __name__ == "__main__":
@@ -132,7 +132,6 @@ def main():
132
132
 
133
133
  axes = load_axes(app_context.args["axes"])
134
134
  site_model = SiteModel(
135
- db_config=app_context.db_config,
136
135
  model_version=app_context.args["model_version"],
137
136
  site=app_context.args["site"],
138
137
  )
@@ -101,7 +101,7 @@ def main():
101
101
  """Run several simtools applications using a configuration file."""
102
102
  app_context = startup_application(_parse, setup_io_handler=False)
103
103
 
104
- simtools_runner.run_applications(app_context.args, app_context.db_config, app_context.logger)
104
+ simtools_runner.run_applications(app_context.args, app_context.logger)
105
105
 
106
106
 
107
107
  if __name__ == "__main__":
@@ -120,13 +120,11 @@ def main():
120
120
  if app_context.args["run_mode"] == "full_simulation":
121
121
  light_source = SimulatorLightEmission(
122
122
  light_emission_config=app_context.args,
123
- db_config=app_context.db_config,
124
123
  label=app_context.args.get("label"),
125
124
  )
126
125
  elif app_context.args["run_mode"] == "direct_injection":
127
126
  light_source = Simulator(
128
127
  args_dict=app_context.args,
129
- db_config=app_context.db_config,
130
128
  label=app_context.args.get("label"),
131
129
  )
132
130
  else:
@@ -120,7 +120,6 @@ def main():
120
120
 
121
121
  light_source = SimulatorLightEmission(
122
122
  light_emission_config=app_context.args,
123
- db_config=app_context.db_config,
124
123
  label=app_context.args.get("label"),
125
124
  )
126
125
  light_source.simulate()
@@ -108,11 +108,7 @@ def main():
108
108
  """Simulate pedestal events."""
109
109
  app_context = startup_application(_parse)
110
110
 
111
- simulator = Simulator(
112
- label=app_context.args.get("label"),
113
- args_dict=app_context.args,
114
- db_config=app_context.db_config,
115
- )
111
+ simulator = Simulator(label=app_context.args.get("label"), args_dict=app_context.args)
116
112
  simulator.simulate()
117
113
 
118
114
 
@@ -127,11 +127,7 @@ def main():
127
127
  """Run simulations for productions."""
128
128
  app_context = startup_application(_parse, setup_io_handler=False)
129
129
 
130
- simulator = Simulator(
131
- label=app_context.args.get("label"),
132
- args_dict=app_context.args,
133
- db_config=app_context.db_config,
134
- )
130
+ simulator = Simulator(label=app_context.args.get("label"), args_dict=app_context.args)
135
131
 
136
132
  simulator.simulate()
137
133
  simulator.validate_metadata()
@@ -22,7 +22,7 @@ Requirements for the 'simtools-simulate-prod-htcondor-generator' application:
22
22
  - Environment parameters required to run CORSIKA and sim_telarray, as well as DB access
23
23
  credentials. These should be listed similarly to a '.env' file and copied to
24
24
  'output_path/env.txt'. Ensure that the path to the simulation software is correctly set to
25
- 'SIMTOOLS_SIMTEL_PATH=/workdir/sim_telarray'.
25
+ 'SIMTOOLS_SIM_TELARRAY_PATH=/workdir/sim_telarray'.
26
26
 
27
27
  To submit jobs, change to the output directory and run:
28
28
 
@@ -75,7 +75,7 @@ def main():
75
75
  """Submit and validate array layouts."""
76
76
  app_context = startup_application(_parse)
77
77
 
78
- db = db_handler.DatabaseHandler(db_config=app_context.db_config)
78
+ db = db_handler.DatabaseHandler()
79
79
 
80
80
  array_layouts = validate_array_layouts_with_db(
81
81
  production_table=db.read_production_table_from_db(
@@ -84,9 +84,7 @@ def main():
84
84
  array_layouts=ascii_handler.collect_data_from_file(app_context.args["array_layouts"]),
85
85
  )
86
86
 
87
- write_array_layouts(
88
- array_layouts=array_layouts, args_dict=app_context.args, db_config=app_context.db_config
89
- )
87
+ write_array_layouts(array_layouts=array_layouts, args_dict=app_context.args)
90
88
 
91
89
 
92
90
  if __name__ == "__main__":
@@ -106,9 +106,7 @@ def main():
106
106
  ),
107
107
  output_path=output_path,
108
108
  metadata_input_dict=app_context.args,
109
- db_config=app_context.db_config
110
- if app_context.args.get("check_parameter_version")
111
- else None,
109
+ check_db_for_existing_parameter=app_context.args.get("check_parameter_version", False),
112
110
  )
113
111
 
114
112
 
@@ -107,7 +107,6 @@ def main():
107
107
  app_context = startup_application(_parse)
108
108
 
109
109
  ce = CameraEfficiency(
110
- db_config=app_context.db_config,
111
110
  label=app_context.args.get("label"),
112
111
  config_data=app_context.args,
113
112
  )
@@ -92,7 +92,6 @@ def main():
92
92
  tel_model = TelescopeModel(
93
93
  site=app_context.args["site"],
94
94
  telescope_name=app_context.args["telescope"],
95
- db_config=app_context.db_config,
96
95
  model_version=app_context.args["model_version"],
97
96
  label=label,
98
97
  )
@@ -130,7 +130,6 @@ def main():
130
130
 
131
131
  tel_model, site_model, _ = initialize_simulation_models(
132
132
  label=app_context.args.get("label"),
133
- db_config=app_context.db_config,
134
133
  site=app_context.args["site"],
135
134
  telescope_name=app_context.args["telescope"],
136
135
  model_version=app_context.args["model_version"],
@@ -142,7 +141,6 @@ def main():
142
141
  ray = RayTracing(
143
142
  telescope_model=tel_model,
144
143
  site_model=site_model,
145
- simtel_path=app_context.args["simtel_path"],
146
144
  zenith_angle=app_context.args["zenith"] * u.deg,
147
145
  source_distance=app_context.args["src_distance"] * u.km,
148
146
  off_axis_angle=[0.0] * u.deg,
@@ -122,23 +122,11 @@ def main():
122
122
 
123
123
  tel_model, site_model, _ = initialize_simulation_models(
124
124
  label=Path(__file__).stem,
125
- db_config=app_context.db_config,
126
125
  site=app_context.args["site"],
127
126
  telescope_name=app_context.args["telescope"],
128
127
  model_version=app_context.args["model_version"],
129
128
  )
130
129
 
131
- ######################################################################
132
- # This is here as an example how to change parameters when necessary.
133
- ######################################################################
134
- # pars_to_change = {
135
- # 'mirror_focal_length': 1608.3,
136
- # 'mirror_offset': -177.5,
137
- # 'camera_body_diameter': 289.7,
138
- # 'telescope_transmission': 1
139
- # }
140
- # tel_model.overwrite_parameters(pars_to_change)
141
-
142
130
  app_context.logger.info(
143
131
  f"\nValidating telescope optics with ray tracing simulations for {tel_model.name}\n"
144
132
  )
@@ -146,7 +134,6 @@ def main():
146
134
  ray = RayTracing(
147
135
  telescope_model=tel_model,
148
136
  site_model=site_model,
149
- simtel_path=app_context.args["simtel_path"],
150
137
  zenith_angle=app_context.args["zenith"] * u.deg,
151
138
  source_distance=app_context.args["src_distance"] * u.km,
152
139
  off_axis_angle=np.linspace(
@@ -22,25 +22,21 @@ class CameraEfficiency:
22
22
 
23
23
  Parameters
24
24
  ----------
25
- db_config: dict
26
- Configuration for the database.
27
25
  label: str
28
26
  Instance label, optional.
29
27
  config_data: dict.
30
28
  Dict containing the configurable parameters.
31
29
  """
32
30
 
33
- def __init__(self, config_data, label, db_config):
31
+ def __init__(self, config_data, label):
34
32
  """Initialize the CameraEfficiency class."""
35
33
  self._logger = logging.getLogger(__name__)
36
34
 
37
- self._simtel_path = config_data.get("simtel_path")
38
35
  self.label = label
39
36
 
40
37
  self.io_handler = io_handler.IOHandler()
41
38
  self.telescope_model, self.site_model, _ = initialize_simulation_models(
42
39
  label=self.label,
43
- db_config=db_config,
44
40
  model_version=config_data["model_version"],
45
41
  site=config_data["site"],
46
42
  telescope_name=config_data["telescope"],
@@ -109,7 +105,6 @@ class CameraEfficiency:
109
105
  self.export_model_files()
110
106
 
111
107
  simtel = SimulatorCameraEfficiency(
112
- simtel_path=self._simtel_path,
113
108
  telescope_model=self.telescope_model,
114
109
  site_model=self.site_model,
115
110
  zenith_angle=self.config["zenith_angle"],
@@ -12,6 +12,7 @@ from astropy.table import Table
12
12
  from scipy.optimize import curve_fit
13
13
 
14
14
  import simtools.data_model.model_data_writer as writer
15
+ from simtools import settings
15
16
  from simtools.constants import MODEL_PARAMETER_SCHEMA_URL, SCHEMA_PATH
16
17
  from simtools.data_model import validate_data
17
18
  from simtools.data_model.metadata_collector import MetadataCollector
@@ -140,7 +141,7 @@ class SinglePhotonElectronSpectrum:
140
141
  )
141
142
 
142
143
  command = [
143
- f"{self.args_dict['simtel_path']}/sim_telarray/bin/norm_spe",
144
+ f"{settings.config.sim_telarray_path}/bin/norm_spe",
144
145
  "-r",
145
146
  f"{self.args_dict['step_size']},{self.args_dict['max_amplitude']}",
146
147
  ]
@@ -106,7 +106,7 @@ class CommandLineParser(argparse.ArgumentParser):
106
106
  required=False,
107
107
  )
108
108
  _job_group.add_argument(
109
- "--simtel_path",
109
+ "--sim_telarray_path",
110
110
  help="path pointing to sim_telarray installation",
111
111
  type=Path,
112
112
  required=False,
@@ -160,6 +160,18 @@ class CommandLineParser(argparse.ArgumentParser):
160
160
  _job_group.add_argument(
161
161
  "--version", action="version", version=f"%(prog)s {simtools.version.__version__}"
162
162
  )
163
+ _job_group.add_argument(
164
+ "--build_info",
165
+ action=BuildInfoAction,
166
+ build_info=f"%(prog)s {simtools.version.__version__}",
167
+ help="show build information and exit",
168
+ )
169
+ _job_group.add_argument(
170
+ "--export_build_info",
171
+ help="export build information to file",
172
+ required=False,
173
+ type=str,
174
+ )
163
175
 
164
176
  def initialize_user_arguments(self):
165
177
  """Initialize user arguments."""
@@ -269,7 +281,7 @@ class CommandLineParser(argparse.ArgumentParser):
269
281
  type=self.telescope,
270
282
  )
271
283
  if "layout" in model_options or "layout_file" in model_options:
272
- _job_group = self._add_model_option_layout(
284
+ self._add_model_option_layout(
273
285
  job_group=_job_group,
274
286
  model_options=model_options,
275
287
  # layout info is always required for layout related tasks with the exception
@@ -825,3 +837,24 @@ class CommandLineParser(argparse.ArgumentParser):
825
837
  raise ValueError("Input string does not contain an integer and a astropy quantity.")
826
838
 
827
839
  return (int(match.group(1)), u.Quantity(float(match.group(2)), match.group(3)))
840
+
841
+
842
+ class BuildInfoAction(argparse.Action):
843
+ """Custom argparse action to display build information."""
844
+
845
+ def __init__(self, option_strings, dest=argparse.SUPPRESS, default=argparse.SUPPRESS, **kwargs):
846
+ """Initialize BuildInfoAction."""
847
+ self.build_info = kwargs.pop("build_info", "Build information")
848
+ kwargs.pop("nargs", None)
849
+ super().__init__(option_strings, dest=dest, default=default, nargs=0, **kwargs)
850
+
851
+ def __call__(self, parser, namespace, values, option_string=None):
852
+ """Display build information and exit."""
853
+ # for efficiency reason, allow import here
854
+ from simtools import dependencies # pylint: disable=C0415
855
+
856
+ build_options = dependencies.get_build_options()
857
+ print(f"{self.build_info}")
858
+ for key, value in build_options.items():
859
+ print(f"{key}: {value}")
860
+ parser.exit()
@@ -2,12 +2,10 @@
2
2
 
3
3
  import argparse
4
4
  import logging
5
- import os
6
5
  import sys
7
6
  import uuid
8
7
 
9
8
  import astropy.units as u
10
- from dotenv import load_dotenv
11
9
 
12
10
  import simtools.configuration.commandline_parser as argparser
13
11
  from simtools.db.mongo_db import jsonschema_db_dict
@@ -305,19 +303,16 @@ class Configurator:
305
303
  Only parameters which are not already configured are changed (i.e., parameter is None).
306
304
 
307
305
  """
306
+ _all_env_dict = gen.load_environment_variables(
307
+ env_file=self.config.get("env_file", None), env_list=self.config.keys()
308
+ )
309
+
308
310
  _env_dict = {}
309
- try:
310
- load_dotenv(self.config["env_file"])
311
- except KeyError:
312
- pass
313
311
  for key, value in self.config.items():
314
- # environmental variables for simtools should always start with SIMTOOLS_
315
- env_variable_to_read = f"SIMTOOLS_{key.upper()}"
316
312
  if value is None:
317
- env_value = os.environ.get(env_variable_to_read)
313
+ env_value = _all_env_dict.get(key)
318
314
  if env_value is not None:
319
- env_value = env_value.split("#")[0].strip().replace('"', "").replace("'", "")
320
- _env_dict[key] = env_value
315
+ _env_dict[key] = env_value
321
316
 
322
317
  self._fill_from_config_dict(_env_dict)
323
318