gammasimtools 0.24.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 (138) hide show
  1. {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/METADATA +2 -1
  2. {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/RECORD +134 -130
  3. {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/entry_points.txt +3 -1
  4. {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/licenses/LICENSE +1 -1
  5. simtools/_version.py +2 -2
  6. simtools/application_control.py +78 -0
  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 +5 -1
  21. simtools/applications/derive_pulse_shape_parameters.py +194 -0
  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 +64 -108
  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 +3 -4
  41. simtools/applications/simulate_illuminator.py +0 -1
  42. simtools/applications/simulate_pedestals.py +2 -6
  43. simtools/applications/simulate_prod.py +9 -28
  44. simtools/applications/simulate_prod_htcondor_generator.py +8 -1
  45. simtools/applications/submit_array_layouts.py +7 -7
  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_file_using_schema.py +49 -123
  51. simtools/applications/validate_optics.py +0 -13
  52. simtools/camera/camera_efficiency.py +1 -6
  53. simtools/camera/single_photon_electron_spectrum.py +2 -1
  54. simtools/configuration/commandline_parser.py +43 -8
  55. simtools/configuration/configurator.py +6 -11
  56. simtools/corsika/corsika_config.py +204 -99
  57. simtools/corsika/corsika_histograms.py +411 -1735
  58. simtools/corsika/primary_particle.py +1 -1
  59. simtools/data_model/metadata_collector.py +5 -2
  60. simtools/data_model/metadata_model.py +0 -4
  61. simtools/data_model/model_data_writer.py +27 -17
  62. simtools/data_model/schema.py +112 -5
  63. simtools/data_model/validate_data.py +80 -48
  64. simtools/db/db_handler.py +19 -8
  65. simtools/db/db_model_upload.py +2 -1
  66. simtools/db/mongo_db.py +133 -42
  67. simtools/dependencies.py +83 -44
  68. simtools/io/ascii_handler.py +4 -2
  69. simtools/io/table_handler.py +1 -1
  70. simtools/job_execution/htcondor_script_generator.py +0 -2
  71. simtools/layout/array_layout.py +4 -12
  72. simtools/layout/array_layout_utils.py +227 -58
  73. simtools/model/array_model.py +37 -18
  74. simtools/model/calibration_model.py +0 -4
  75. simtools/model/legacy_model_parameter.py +134 -0
  76. simtools/model/model_parameter.py +24 -14
  77. simtools/model/model_repository.py +18 -5
  78. simtools/model/model_utils.py +1 -6
  79. simtools/model/site_model.py +0 -4
  80. simtools/model/telescope_model.py +6 -11
  81. simtools/production_configuration/derive_corsika_limits.py +6 -11
  82. simtools/production_configuration/interpolation_handler.py +16 -16
  83. simtools/ray_tracing/incident_angles.py +5 -11
  84. simtools/ray_tracing/mirror_panel_psf.py +3 -7
  85. simtools/ray_tracing/psf_analysis.py +29 -27
  86. simtools/ray_tracing/psf_parameter_optimisation.py +822 -680
  87. simtools/ray_tracing/ray_tracing.py +6 -15
  88. simtools/reporting/docs_auto_report_generator.py +8 -13
  89. simtools/reporting/docs_read_parameters.py +70 -16
  90. simtools/runners/corsika_runner.py +15 -10
  91. simtools/runners/corsika_simtel_runner.py +9 -8
  92. simtools/runners/runner_services.py +17 -7
  93. simtools/runners/simtel_runner.py +11 -58
  94. simtools/runners/simtools_runner.py +2 -4
  95. simtools/schemas/model_parameters/flasher_pulse_exp_decay.schema.yml +2 -0
  96. simtools/schemas/model_parameters/flasher_pulse_shape.schema.yml +50 -0
  97. simtools/schemas/model_parameters/flasher_pulse_width.schema.yml +2 -0
  98. simtools/schemas/simulation_models_info.schema.yml +2 -0
  99. simtools/settings.py +154 -0
  100. simtools/sim_events/file_info.py +128 -0
  101. simtools/{simtel/simtel_io_event_histograms.py → sim_events/histograms.py} +25 -15
  102. simtools/{simtel/simtel_io_event_reader.py → sim_events/reader.py} +20 -17
  103. simtools/{simtel/simtel_io_event_writer.py → sim_events/writer.py} +84 -25
  104. simtools/simtel/pulse_shapes.py +273 -0
  105. simtools/simtel/simtel_config_writer.py +146 -22
  106. simtools/simtel/simtel_table_reader.py +6 -4
  107. simtools/simtel/simulator_array.py +62 -23
  108. simtools/simtel/simulator_camera_efficiency.py +4 -6
  109. simtools/simtel/simulator_light_emission.py +101 -19
  110. simtools/simtel/simulator_ray_tracing.py +4 -10
  111. simtools/simulator.py +360 -353
  112. simtools/telescope_trigger_rates.py +3 -4
  113. simtools/testing/assertions.py +115 -8
  114. simtools/testing/configuration.py +2 -3
  115. simtools/testing/helpers.py +2 -3
  116. simtools/testing/log_inspector.py +5 -1
  117. simtools/testing/sim_telarray_metadata.py +1 -1
  118. simtools/testing/validate_output.py +69 -23
  119. simtools/utils/general.py +37 -0
  120. simtools/utils/geometry.py +0 -77
  121. simtools/utils/names.py +7 -9
  122. simtools/version.py +37 -0
  123. simtools/visualization/legend_handlers.py +21 -10
  124. simtools/visualization/plot_array_layout.py +312 -41
  125. simtools/visualization/plot_corsika_histograms.py +143 -605
  126. simtools/visualization/plot_mirrors.py +834 -0
  127. simtools/visualization/plot_pixels.py +2 -4
  128. simtools/visualization/plot_psf.py +0 -1
  129. simtools/visualization/plot_simtel_event_histograms.py +4 -4
  130. simtools/visualization/plot_simtel_events.py +6 -11
  131. simtools/visualization/plot_tables.py +8 -19
  132. simtools/visualization/visualize.py +22 -2
  133. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +0 -160
  134. simtools/applications/print_version.py +0 -53
  135. simtools/io/hdf5_handler.py +0 -139
  136. simtools/simtel/simtel_io_file_info.py +0 -62
  137. {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/WHEEL +0 -0
  138. {gammasimtools-0.24.0.dist-info → gammasimtools-0.26.0.dist-info}/top_level.txt +0 -0
@@ -3,26 +3,25 @@ r"""
3
3
  Validate a file or files in a directory using a schema.
4
4
 
5
5
  Input files can be metadata, schema, or data files in yaml, json, or ecsv format.
6
+ For model parameters, the schema files are taken from the simtools model parameter
7
+ schema directory by default.
6
8
 
7
9
  Command line arguments
8
10
  ----------------------
9
11
  file_name (str)
10
12
  input file to be validated
11
- model_parameters_directory (str)
13
+ file_directory (str)
12
14
  directory with json files of model parameters to be validated
13
15
  schema (str)
14
16
  schema file (jsonschema format) used for validation
15
17
  data_type (str)
16
- type of input data (allowed types: metadata, schema, data)
17
-
18
- Raises
19
- ------
20
- FileNotFoundError
21
- if file to be validated is not found
18
+ type of input data (allowed types: metadata, schema, data, model_parameter)
22
19
 
23
20
  Example
24
21
  -------
25
22
 
23
+ Validate metadata of a file:
24
+
26
25
  .. code-block:: console
27
26
 
28
27
  simtools-validate-file-using-schema \\
@@ -30,16 +29,29 @@ r"""
30
29
  --schema simtools/schemas/metadata.metaschema.yml \\
31
30
  --data_type metadata
32
31
 
33
- """
32
+ Validate schema of a file:
33
+
34
+ .. code-block:: console
35
+
36
+ simtools-validate-file-using-schema \\
37
+ --file_name tests/resources/model_parameters/schema-0.3.0/num_gains-1.0.0.json \\
38
+ --schema src/simtools/schemas/model_parameter.metaschema.yml \\
39
+ --data_type schema
34
40
 
35
- import re
36
- from pathlib import Path
41
+ Validate all model parameter files in a directory:
42
+
43
+ .. code-block:: console
44
+
45
+ simtools-validate-file-using-schema \\
46
+ --file_directory tests/resources/model_parameters \\
47
+ --data_type model_parameter
48
+
49
+ """
37
50
 
38
51
  from simtools.application_control import get_application_label, startup_application
39
52
  from simtools.configuration import configurator
40
53
  from simtools.constants import MODEL_PARAMETER_SCHEMA_PATH
41
54
  from simtools.data_model import metadata_collector, schema, validate_data
42
- from simtools.io import ascii_handler
43
55
 
44
56
 
45
57
  def _parse():
@@ -62,7 +74,7 @@ def _parse():
62
74
  f"{MODEL_PARAMETER_SCHEMA_PATH}."
63
75
  ),
64
76
  )
65
- config.parser.add_argument("--schema", help="Json schema file", required=False)
77
+ config.parser.add_argument("--schema", help="Schema file", required=False)
66
78
  config.parser.add_argument(
67
79
  "--data_type",
68
80
  help="Type of input data",
@@ -70,7 +82,7 @@ def _parse():
70
82
  default="data",
71
83
  )
72
84
  config.parser.add_argument(
73
- "--require_exact_data_type",
85
+ "--check_exact_data_type",
74
86
  help="Require exact data type for validation",
75
87
  action="store_true",
76
88
  )
@@ -82,121 +94,35 @@ def _parse():
82
94
  return config.initialize(paths=False)
83
95
 
84
96
 
85
- def _get_schema_file_name(args_dict, data_dict=None):
86
- """
87
- Get schema file name from metadata, data dict, or from command line argument.
88
-
89
- Parameters
90
- ----------
91
- args_dict (dict)
92
- command line arguments
93
- data_dict (dict)
94
- dictionary with metaschema information
95
-
96
- Returns
97
- -------
98
- schema_file: str
99
- schema file name
100
-
101
- """
102
- schema_file = args_dict.get("schema")
103
- if schema_file is None and data_dict is not None:
104
- schema_file = data_dict.get("meta_schema_url")
105
- if schema_file is None:
106
- metadata = metadata_collector.MetadataCollector(
107
- None, metadata_file_name=args_dict["file_name"]
108
- )
109
- schema_file = metadata.get_data_model_schema_file_name()
110
- return schema_file
111
-
112
-
113
- def _get_file_list(file_directory=None, file_name="*.json"):
114
- """Return list of files in a directory."""
115
- file_list = []
116
- if file_directory is not None:
117
- file_list = list(Path(file_directory).rglob(file_name))
118
- if not file_list:
119
- raise FileNotFoundError(f"No files found in {file_directory}")
120
- elif file_name is not None:
121
- file_list = [file_name]
122
-
123
- return file_list
124
-
125
-
126
- def validate_dict_using_schema(args_dict, logger):
127
- """
128
- Validate a schema file (or several files) given in yaml or json format.
129
-
130
- This function validate all documents in a multi-document YAML file.
131
- Schema is either given as command line argument, read from the meta_schema_url or from
132
- the metadata section of the data dictionary.
133
-
134
- """
135
- for file_name in _get_file_list(args_dict.get("file_directory"), args_dict.get("file_name")):
136
- try:
137
- data = ascii_handler.collect_data_from_file(file_name=file_name)
138
- except FileNotFoundError as exc:
139
- raise FileNotFoundError(f"Error reading schema file from {file_name}") from exc
140
- data = data if isinstance(data, list) else [data]
141
- try:
142
- for data_dict in data:
143
- schema.validate_dict_using_schema(
144
- data_dict,
145
- _get_schema_file_name(args_dict, data_dict),
146
- ignore_software_version=args_dict.get("ignore_software_version", False),
147
- )
148
- except Exception as exc:
149
- raise ValueError(f"Validation of file {file_name} failed") from exc
150
- logger.info(f"Successful validation of file {file_name}")
151
-
152
-
153
- def validate_data_files(args_dict, logger):
154
- """Validate data files."""
155
- if args_dict.get("file_directory") is not None:
156
- tmp_args_dict = {}
157
- for file_name in _get_file_list(args_dict.get("file_directory")):
158
- tmp_args_dict["file_name"] = file_name
159
- parameter_name = re.sub(r"-\d+\.\d+\.\d+", "", file_name.stem)
160
- schema_file = schema.get_model_parameter_schema_file(f"{parameter_name}")
161
- tmp_args_dict["schema"] = schema_file
162
- tmp_args_dict["data_type"] = "model_parameter"
163
- tmp_args_dict["require_exact_data_type"] = args_dict["require_exact_data_type"]
164
- validate_data_file(tmp_args_dict, logger)
165
- else:
166
- validate_data_file(args_dict, logger)
167
-
168
-
169
- def validate_data_file(args_dict, logger):
170
- """Validate a data file (e.g., in ecsv, json, yaml format)."""
171
- data_validator = validate_data.DataValidator(
172
- schema_file=_get_schema_file_name(args_dict),
173
- data_file=args_dict["file_name"],
174
- check_exact_data_type=args_dict["require_exact_data_type"],
175
- )
176
- data_validator.validate_and_transform(
177
- is_model_parameter=(args_dict["data_type"].lower() == "model_parameter")
178
- )
179
-
180
- logger.info(f"Successful validation of data file {args_dict['file_name']}")
181
-
182
-
183
- def validate_metadata(args_dict, logger):
184
- """Validate metadata."""
185
- # metadata_collector runs the metadata validation by default, no need to do anything else
186
- metadata_collector.MetadataCollector(None, metadata_file_name=args_dict["file_name"])
187
- logger.info(f"Successful validation of metadata {args_dict['file_name']}")
188
-
189
-
190
97
  def main():
191
98
  """Validate a file or files in a directory using a schema."""
192
99
  app_context = startup_application(_parse)
193
100
 
194
- if app_context.args["data_type"].lower() == "metadata":
195
- validate_metadata(app_context.args, app_context.logger)
196
- elif app_context.args["data_type"].lower() == "schema":
197
- validate_dict_using_schema(app_context.args, app_context.logger)
101
+ file_name = app_context.args.get("file_name")
102
+ file_directory = app_context.args.get("file_directory")
103
+ schema_file = app_context.args.get("schema")
104
+ data_type = app_context.args.get("data_type").lower()
105
+
106
+ if data_type == "metadata":
107
+ # metadata_collector runs the metadata validation by default, no need to do anything else
108
+ metadata_collector.MetadataCollector(None, metadata_file_name=file_name)
109
+ app_context.logger.info(f"Successful validation of metadata {file_name}")
110
+
111
+ elif data_type == "schema":
112
+ schema.validate_schema_from_files(
113
+ file_directory=file_directory,
114
+ file_name=file_name,
115
+ schema_file=schema_file,
116
+ ignore_software_version=app_context.args.get("ignore_software_version", False),
117
+ )
198
118
  else:
199
- validate_data_files(app_context.args, app_context.logger)
119
+ validate_data.DataValidator.validate_data_files(
120
+ file_name=file_name,
121
+ file_directory=file_directory,
122
+ is_model_parameter=(data_type == "model_parameter"),
123
+ check_exact_data_type=app_context.args.get("check_exact_data_type", False),
124
+ schema_file=schema_file,
125
+ )
200
126
 
201
127
 
202
128
  if __name__ == "__main__":
@@ -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
@@ -377,12 +389,6 @@ class CommandLineParser(argparse.ArgumentParser):
377
389
  "required": True,
378
390
  "default": 1,
379
391
  },
380
- "number_of_runs": {
381
- "help": "Number of runs to be simulated.",
382
- "type": int,
383
- "required": True,
384
- "default": 1,
385
- },
386
392
  "event_number_first_shower": {
387
393
  "help": "Event number of first shower",
388
394
  "type": int,
@@ -395,6 +401,14 @@ class CommandLineParser(argparse.ArgumentParser):
395
401
  "required": False,
396
402
  "default": True,
397
403
  },
404
+ "curved_atmosphere_min_zenith_angle": {
405
+ "help": (
406
+ "Minimum zenith angle (deg) for using curved-atmosphere CORSIKA binaries. "
407
+ ),
408
+ "type": CommandLineParser.zenith_angle,
409
+ "required": False,
410
+ "default": 65 * u.deg,
411
+ },
398
412
  }
399
413
 
400
414
  @staticmethod
@@ -823,3 +837,24 @@ class CommandLineParser(argparse.ArgumentParser):
823
837
  raise ValueError("Input string does not contain an integer and a astropy quantity.")
824
838
 
825
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