gammasimtools 0.9.0__py3-none-any.whl → 0.11.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 (135) hide show
  1. {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/METADATA +4 -2
  2. {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/RECORD +133 -117
  3. {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/entry_points.txt +6 -1
  5. simtools/_version.py +9 -4
  6. simtools/applications/calculate_trigger_rate.py +15 -38
  7. simtools/applications/convert_all_model_parameters_from_simtel.py +9 -29
  8. simtools/applications/convert_geo_coordinates_of_array_elements.py +47 -45
  9. simtools/applications/convert_model_parameter_from_simtel.py +2 -3
  10. simtools/applications/db_add_file_to_db.py +1 -3
  11. simtools/applications/db_add_simulation_model_from_repository_to_db.py +110 -0
  12. simtools/applications/db_add_value_from_json_to_db.py +1 -2
  13. simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +6 -6
  14. simtools/applications/db_get_file_from_db.py +11 -12
  15. simtools/applications/db_get_parameter_from_db.py +26 -35
  16. simtools/applications/derive_mirror_rnda.py +1 -2
  17. simtools/applications/derive_photon_electron_spectrum.py +99 -0
  18. simtools/applications/derive_psf_parameters.py +1 -0
  19. simtools/applications/docs_produce_array_element_report.py +71 -0
  20. simtools/applications/docs_produce_model_parameter_reports.py +63 -0
  21. simtools/applications/generate_array_config.py +17 -17
  22. simtools/applications/generate_corsika_histograms.py +2 -2
  23. simtools/applications/generate_regular_arrays.py +19 -17
  24. simtools/applications/generate_simtel_array_histograms.py +11 -48
  25. simtools/applications/production_derive_limits.py +95 -0
  26. simtools/applications/production_generate_simulation_config.py +37 -33
  27. simtools/applications/production_scale_events.py +4 -9
  28. simtools/applications/run_application.py +165 -0
  29. simtools/applications/simulate_light_emission.py +0 -4
  30. simtools/applications/simulate_prod.py +1 -1
  31. simtools/applications/simulate_prod_htcondor_generator.py +26 -26
  32. simtools/applications/submit_data_from_external.py +12 -4
  33. simtools/applications/submit_model_parameter_from_external.py +18 -11
  34. simtools/applications/validate_camera_efficiency.py +2 -2
  35. simtools/applications/validate_file_using_schema.py +26 -22
  36. simtools/camera/single_photon_electron_spectrum.py +168 -0
  37. simtools/configuration/commandline_parser.py +37 -1
  38. simtools/configuration/configurator.py +8 -10
  39. simtools/constants.py +10 -3
  40. simtools/corsika/corsika_config.py +19 -17
  41. simtools/corsika/corsika_histograms.py +5 -7
  42. simtools/corsika/corsika_histograms_visualize.py +2 -4
  43. simtools/data_model/data_reader.py +0 -3
  44. simtools/data_model/metadata_collector.py +20 -12
  45. simtools/data_model/metadata_model.py +8 -124
  46. simtools/data_model/model_data_writer.py +81 -75
  47. simtools/data_model/schema.py +220 -0
  48. simtools/data_model/validate_data.py +79 -68
  49. simtools/db/db_handler.py +350 -492
  50. simtools/db/db_model_upload.py +139 -0
  51. simtools/dependencies.py +112 -0
  52. simtools/io_operations/hdf5_handler.py +54 -24
  53. simtools/layout/array_layout.py +38 -32
  54. simtools/model/array_model.py +13 -7
  55. simtools/model/model_parameter.py +55 -54
  56. simtools/model/site_model.py +2 -2
  57. simtools/production_configuration/calculate_statistical_errors_grid_point.py +119 -145
  58. simtools/production_configuration/event_scaler.py +9 -35
  59. simtools/production_configuration/generate_simulation_config.py +9 -44
  60. simtools/production_configuration/interpolation_handler.py +9 -15
  61. simtools/production_configuration/limits_calculation.py +202 -0
  62. simtools/reporting/docs_read_parameters.py +310 -0
  63. simtools/runners/corsika_simtel_runner.py +4 -4
  64. simtools/schemas/{integration_tests_config.metaschema.yml → application_workflow.metaschema.yml} +61 -27
  65. simtools/schemas/array_elements.yml +8 -0
  66. simtools/schemas/input/MST_mirror_2f_measurements.schema.yml +39 -0
  67. simtools/schemas/input/single_pe_spectrum.schema.yml +38 -0
  68. simtools/schemas/model_parameter.metaschema.yml +103 -2
  69. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +4 -1
  70. simtools/schemas/model_parameters/array_element_position_utm.schema.yml +1 -1
  71. simtools/schemas/model_parameters/array_window.schema.yml +37 -0
  72. simtools/schemas/model_parameters/asum_clipping.schema.yml +0 -4
  73. simtools/schemas/model_parameters/channels_per_chip.schema.yml +1 -1
  74. simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +1 -1
  75. simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +2 -0
  76. simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +2 -0
  77. simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +2 -0
  78. simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +4 -2
  79. simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +2 -0
  80. simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +2 -0
  81. simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +2 -0
  82. simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +2 -0
  83. simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +2 -0
  84. simtools/schemas/model_parameters/dsum_clipping.schema.yml +0 -2
  85. simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +0 -2
  86. simtools/schemas/model_parameters/dsum_offset.schema.yml +0 -2
  87. simtools/schemas/model_parameters/dsum_pedsub.schema.yml +0 -2
  88. simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +0 -2
  89. simtools/schemas/model_parameters/dsum_prescale.schema.yml +0 -2
  90. simtools/schemas/model_parameters/dsum_presum_max.schema.yml +0 -2
  91. simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +0 -2
  92. simtools/schemas/model_parameters/dsum_shaping.schema.yml +0 -2
  93. simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +0 -2
  94. simtools/schemas/model_parameters/dsum_threshold.schema.yml +0 -2
  95. simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +0 -2
  96. simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +1 -1
  97. simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +1 -1
  98. simtools/schemas/model_parameters/fadc_noise.schema.yml +3 -3
  99. simtools/schemas/model_parameters/fake_mirror_list.schema.yml +33 -0
  100. simtools/schemas/model_parameters/iobuf_maximum.schema.yml +1 -1
  101. simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +1 -1
  102. simtools/schemas/model_parameters/laser_photons.schema.yml +2 -2
  103. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +1 -1
  104. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +1 -1
  105. simtools/schemas/model_parameters/min_photoelectrons.schema.yml +1 -1
  106. simtools/schemas/model_parameters/min_photons.schema.yml +1 -1
  107. simtools/schemas/model_parameters/random_generator.schema.yml +1 -1
  108. simtools/schemas/model_parameters/sampled_output.schema.yml +1 -1
  109. simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +1 -1
  110. simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +1 -1
  111. simtools/schemas/model_parameters/store_photoelectrons.schema.yml +1 -1
  112. simtools/schemas/model_parameters/tailcut_scale.schema.yml +1 -1
  113. simtools/schemas/production_configuration_metrics.schema.yml +68 -0
  114. simtools/schemas/production_tables.schema.yml +41 -0
  115. simtools/simtel/simtel_config_reader.py +1 -2
  116. simtools/simtel/simtel_config_writer.py +6 -8
  117. simtools/simtel/simtel_io_histogram.py +32 -68
  118. simtools/simtel/simtel_io_histograms.py +17 -34
  119. simtools/simtel/simulator_array.py +2 -1
  120. simtools/simtel/simulator_camera_efficiency.py +6 -3
  121. simtools/simtel/simulator_light_emission.py +5 -6
  122. simtools/simtel/simulator_ray_tracing.py +3 -4
  123. simtools/testing/configuration.py +2 -1
  124. simtools/testing/helpers.py +6 -13
  125. simtools/testing/validate_output.py +141 -47
  126. simtools/utils/general.py +114 -14
  127. simtools/utils/names.py +299 -157
  128. simtools/utils/value_conversion.py +17 -13
  129. simtools/version.py +2 -2
  130. simtools/visualization/legend_handlers.py +2 -0
  131. simtools/applications/db_add_model_parameters_from_repository_to_db.py +0 -176
  132. simtools/db/db_array_elements.py +0 -130
  133. {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/LICENSE +0 -0
  134. {gammasimtools-0.9.0.dist-info → gammasimtools-0.11.0.dist-info}/top_level.txt +0 -0
  135. /simtools/{camera_efficiency.py → camera/camera_efficiency.py} +0 -0
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/python3
2
+
3
+ r"""
4
+ Derives the limits for energy, radial distance, and viewcone to be used in CORSIKA simulations.
5
+
6
+ The limits are derived based on the event loss fraction specified by the user.
7
+
8
+ Command line arguments
9
+ ----------------------
10
+ event_data_file (str, required)
11
+ Path to the file containing the event data.
12
+ loss_fraction (float, required)
13
+ Fraction of events to be lost.
14
+
15
+
16
+ Example
17
+ -------
18
+ Derive limits for a given file with a specified loss fraction.
19
+
20
+ .. code-block:: console
21
+
22
+ simtools-production-derive-limits\\
23
+ --event_data_file path/to/event_data_file.hdf5 \\
24
+ --loss_fraction 1e-6
25
+ """
26
+
27
+ import logging
28
+
29
+ import simtools.utils.general as gen
30
+ from simtools.configuration import configurator
31
+ from simtools.io_operations.hdf5_handler import read_hdf5
32
+ from simtools.production_configuration.limits_calculation import LimitCalculator
33
+
34
+ _logger = logging.getLogger(__name__)
35
+
36
+
37
+ def _parse():
38
+ """
39
+ Parse command line configuration.
40
+
41
+ Parameters
42
+ ----------
43
+ event_data_file: str
44
+ The event data file.
45
+ loss_fraction: float
46
+ Loss fraction of events for limit derivation.
47
+
48
+ Returns
49
+ -------
50
+ CommandLineParser
51
+ Command line parser object
52
+
53
+ """
54
+ config = configurator.Configurator(
55
+ description="Derive limits for energy, radial distance, and viewcone."
56
+ )
57
+ config.parser.add_argument(
58
+ "--event_data_file",
59
+ type=str,
60
+ required=True,
61
+ help="Path to the event data file containing the event data.",
62
+ )
63
+ config.parser.add_argument(
64
+ "--loss_fraction", type=float, required=True, help="Fraction of events to be lost."
65
+ )
66
+ return config.initialize(db_config=False)
67
+
68
+
69
+ def main():
70
+ """Derive limits for energy, radial distance, and viewcone."""
71
+ args_dict, _ = _parse()
72
+
73
+ logger = logging.getLogger()
74
+ logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
75
+
76
+ event_data_file_path = args_dict["event_data_file"]
77
+ loss_fraction = args_dict["loss_fraction"]
78
+
79
+ _logger.info(f"Loading event data file: {event_data_file_path}")
80
+ tables = read_hdf5(event_data_file_path)
81
+
82
+ calculator = LimitCalculator(tables)
83
+
84
+ lower_energy_limit = calculator.compute_lower_energy_limit(loss_fraction)
85
+ _logger.info(f"Lower energy threshold: {lower_energy_limit}")
86
+
87
+ upper_radial_distance = calculator.compute_upper_radial_distance(loss_fraction)
88
+ _logger.info(f"Upper radius threshold: {upper_radial_distance}")
89
+
90
+ viewcone = calculator.compute_viewcone(loss_fraction)
91
+ _logger.info(f"Viewcone radius: {viewcone}")
92
+
93
+
94
+ if __name__ == "__main__":
95
+ main()
@@ -1,32 +1,42 @@
1
1
  #!/usr/bin/python3
2
2
 
3
3
  r"""
4
- Configure a simulation based on command-line arguments.
4
+ Derive simulation configuration parameters for a simulation production.
5
5
 
6
- This application configures and
7
- generates simulation parameters for a specific grid point in a statistical uncertainty
8
- evaluation setup.
6
+ Derived simulation configuration parameters include:
7
+
8
+ * energy range
9
+ * shower core scatter radius
10
+ * view cone radius
11
+ * total number of events to be simulated
12
+
13
+ Configuration parameters depend on characteristics of the observations, especially elevation,
14
+ azimuth, and night sky background.
15
+
16
+ The configuration parameters are derived according to the required precision. The metrics are:
17
+
18
+ * statistical uncertainty on the determination of the effective area as function of primary energy
19
+ * fraction of lost events to the selected core scatter and view cone radius (to be implemented)
20
+ * statistical uncertainty of the energy migration matrix as function of primary energy
21
+ (to be implemented)
9
22
 
10
23
  Command line arguments
11
24
  ----------------------
12
25
  azimuth (float, required)
13
- Azimuth angle in degrees.
26
+ Azimuth angle in degrees.
14
27
  elevation (float, required)
15
- Elevation angle in degrees.
28
+ Elevation angle in degrees.
16
29
  nsb (float, required)
17
- Night sky background value.
18
- ctao_data_level (str, required)
19
- The data level for the simulation (e.g., 'A', 'B', 'C').
20
- science_case (str, required)
21
- The science case for the simulation.
30
+ Night sky background value.
22
31
  file_path (str, required)
23
- Path to file with MC events at CTAO DL2 data level. Used for statistical uncertainty evaluation.
32
+ Path to file with MC events at CTAO DL2 data level.
33
+ Used for statistical uncertainty evaluation.
24
34
  file_type (str, required)
25
- Type of the DL2 MC event file ('point-like' or 'cone').
26
- metrics (str, optional)
27
- Path to a YAML file containing metrics for evaluation.
35
+ Type of the DL2 MC event file ('point-like' or 'cone').
36
+ metrics (str, required)
37
+ Path to a YAML file containing metrics for evaluation.
28
38
  site (str, required)
29
- The observatory site (North or South).
39
+ The observatory site (North or South).
30
40
 
31
41
  Example
32
42
  -------
@@ -34,13 +44,12 @@ To run the simulation configuration, execute the script as follows:
34
44
 
35
45
  .. code-block:: console
36
46
 
37
- simtools-production-generate-simulation-config --azimuth 60.0 --elevation 45.0 \
38
- --nsb 0.3 --ctao_data_level "A" --science_case "high_precision" \
39
- --file_path tests/resources/production_dl2_fits/dl2_mc_events_file.fits \
40
- --file_type "point-like" \
41
- --metrics_file tests/resources/production_simulation_config_metrics.yaml --site North
47
+ simtools-production-generate-simulation-config --azimuth 60.0 --elevation 45.0 \
48
+ --nsb 0.3 --file_path tests/resources/production_dl2_fits/dl2_mc_events_file.fits \
49
+ --file_type "point-like" \
50
+ --metrics_file tests/resources/production_simulation_config_metrics.yml --site North
42
51
 
43
- The output will show the configured simulation parameters.
52
+ The output will show the derived simulation parameters.
44
53
  """
45
54
 
46
55
  import json
@@ -51,6 +60,7 @@ import astropy.units as u
51
60
 
52
61
  import simtools.utils.general as gen
53
62
  from simtools.configuration import configurator
63
+ from simtools.data_model import schema
54
64
  from simtools.io_operations import io_handler
55
65
  from simtools.production_configuration.generate_simulation_config import (
56
66
  SimulationConfig,
@@ -60,7 +70,8 @@ from simtools.production_configuration.generate_simulation_config import (
60
70
  def _parse(label):
61
71
  """Parse command-line arguments."""
62
72
  config = configurator.Configurator(
63
- label=label, description="Configure and run a simulation based on input parameters."
73
+ label=label,
74
+ description="Derive simulation configuration parameters for a simulation production.",
64
75
  )
65
76
  config.parser.add_argument(
66
77
  "--azimuth", type=float, required=True, help="Azimuth angle in degrees."
@@ -71,12 +82,6 @@ def _parse(label):
71
82
  config.parser.add_argument(
72
83
  "--nsb", type=float, required=True, help="Night sky background in units of 1/(sr*ns*cm**2)."
73
84
  )
74
- config.parser.add_argument(
75
- "--ctao_data_level", type=str, required=True, help="Data level (e.g., 'A', 'B', 'C')."
76
- )
77
- config.parser.add_argument(
78
- "--science_case", type=str, required=True, help="Science case for the simulation."
79
- )
80
85
  config.parser.add_argument(
81
86
  "--file_path", type=str, required=True, help="Path to MC event file in DL2 format."
82
87
  )
@@ -125,14 +130,13 @@ def main():
125
130
  "night_sky_background": args_dict["nsb"],
126
131
  }
127
132
 
128
- metrics = (
129
- gen.collect_data_from_file(args_dict["metrics_file"]) if "metrics_file" in args_dict else {}
133
+ metrics = gen.collect_data_from_file(args_dict["metrics_file"])
134
+ schema.validate_dict_using_schema(
135
+ data=metrics, schema_file="production_configuration_metrics.schema.yml"
130
136
  )
131
137
 
132
138
  simulation_config = SimulationConfig(
133
139
  grid_point=grid_point_config,
134
- ctao_data_level=args_dict["ctao_data_level"],
135
- science_case=args_dict["science_case"],
136
140
  file_path=args_dict["file_path"],
137
141
  file_type=args_dict["file_type"],
138
142
  metrics=metrics,
@@ -28,7 +28,7 @@ To evaluate statistical uncertainties and perform interpolation, run the command
28
28
 
29
29
  simtools-production-scale-events --base_path tests/resources/production_dl2_fits/ \
30
30
  --zeniths 20 52 40 60 --offsets 0 --interpolate --query_point 1 180 30 0 0 \
31
- --science_case 1 --metrics_file "path/to/metrics.yaml"
31
+ --metrics_file "path/to/metrics.yaml"
32
32
 
33
33
 
34
34
  The output will display the scaled events for the specified grid point.
@@ -93,11 +93,8 @@ def _parse(label, description):
93
93
  config.parser.add_argument(
94
94
  "--metrics_file",
95
95
  type=str,
96
- default="production_simulation_config_metrics.yaml",
97
- help="Metrics definition file. (default: production_simulation_config_metrics.yaml)",
98
- )
99
- config.parser.add_argument(
100
- "--science_case", type=str, required=True, help="Science case for the simulation."
96
+ default="production_simulation_config_metrics.yml",
97
+ help="Metrics definition file. (default: production_simulation_config_metrics.yml)",
101
98
  )
102
99
  return config.initialize(db_config=False)
103
100
 
@@ -147,9 +144,7 @@ def main():
147
144
  logger.warning(f"Offsets: {args_dict['offsets']}")
148
145
 
149
146
  # Perform interpolation for the given query point
150
- interpolation_handler = InterpolationHandler(
151
- evaluator_instances, science_case=args_dict["science_case"], metrics=metrics
152
- )
147
+ interpolation_handler = InterpolationHandler(evaluator_instances, metrics=metrics)
153
148
  query_points = np.array([args_dict["query_point"]])
154
149
  scaled_events = interpolation_handler.interpolate(query_points)
155
150
 
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/python3
2
+
3
+ """
4
+ Run simtools applications from configuration files for setting workflows.
5
+
6
+ Allows to run several simtools applications with a single configuration file, which includes
7
+ both the name of the simtools application and the configuration for the application.
8
+
9
+ Strong assumption on the directory structure for input and output files of applications.
10
+
11
+ """
12
+
13
+ import logging
14
+ import subprocess
15
+ import tempfile
16
+ from pathlib import Path
17
+
18
+ import yaml
19
+
20
+ import simtools.utils.general as gen
21
+ from simtools import dependencies
22
+ from simtools.configuration import configurator
23
+
24
+
25
+ def _parse(label, description, usage):
26
+ """
27
+ Parse command line configuration.
28
+
29
+ Parameters
30
+ ----------
31
+ label : str
32
+ Label describing the application.
33
+ description : str
34
+ Description of the application.
35
+ usage : str
36
+ Example on how to use the application.
37
+
38
+ Returns
39
+ -------
40
+ CommandLineParser
41
+ Command line parser object.
42
+ """
43
+ config = configurator.Configurator(label=label, description=description, usage=usage)
44
+
45
+ config.parser.add_argument(
46
+ "--configuration_file",
47
+ help="Application configuration.",
48
+ type=str,
49
+ required=True,
50
+ default=None,
51
+ )
52
+ return config.initialize(db_config=False)
53
+
54
+
55
+ def run_application(application, configuration, logger):
56
+ """Run a simtools application and return stdout and stderr."""
57
+ with tempfile.NamedTemporaryFile(mode="w", delete=True, suffix=".yml") as temp_config:
58
+ yaml.dump(configuration, temp_config, default_flow_style=False)
59
+ temp_config.flush()
60
+ configuration_file = Path(temp_config.name)
61
+ try:
62
+ result = subprocess.run(
63
+ [application, "--config", configuration_file],
64
+ check=True,
65
+ capture_output=True,
66
+ text=True,
67
+ )
68
+ except subprocess.CalledProcessError as exc:
69
+ logger.error(f"Error running application {application}: {exc.stderr}")
70
+ raise exc
71
+ return result.stdout, result.stderr
72
+
73
+
74
+ def get_subdirectory_name(path):
75
+ """Get the first subdirectory name under 'input'."""
76
+ path = Path(path).resolve()
77
+ try:
78
+ input_index = path.parts.index("input")
79
+ return path.parts[input_index], path.parts[input_index + 1]
80
+ except (ValueError, IndexError) as exc:
81
+ raise ValueError(f"Could not find subdirectory under 'input': {exc}") from exc
82
+
83
+
84
+ def read_application_configuration(configuration_file, logger):
85
+ """
86
+ Read application configuration from file and modify for setting workflows.
87
+
88
+ Strong assumptions on the structure of input and output files:
89
+
90
+ - configuration file is expected to be in './input/<workflow directory>/<yaml file>'
91
+ - output files will be written out to './output/<workflow directory>/'
92
+
93
+ Replaces the placeholders in the configuration file with the actual values.
94
+ Sets 'USE_PLAIN_OUTPUT_PATH' to True for all applications.
95
+
96
+ Parameters
97
+ ----------
98
+ configuration_file : str
99
+ Configuration file name.
100
+ logger : Logger
101
+ Logger object.
102
+
103
+ Returns
104
+ -------
105
+ dict
106
+ Application configuration.
107
+ Path
108
+ Path to the log file.
109
+
110
+ """
111
+ application_config = gen.collect_data_from_file(configuration_file).get("CTA_SIMPIPE")
112
+ place_holder = "__SETTING_WORKFLOW__"
113
+ workflow_dir, setting_workflow = get_subdirectory_name(configuration_file)
114
+ output_path = str(workflow_dir).replace("input", "output") + setting_workflow
115
+ logger.info(f"Setting workflow output path to {output_path}")
116
+ log_file = (
117
+ Path(application_config.get("LOG_PATH", "./").replace(place_holder, setting_workflow))
118
+ / "simtools.log"
119
+ )
120
+ log_file.parent.mkdir(parents=True, exist_ok=True)
121
+ configurations = application_config.get("APPLICATIONS")
122
+ for config in configurations:
123
+ for key, value in config.get("CONFIGURATION", {}).items():
124
+ if isinstance(value, str):
125
+ config["CONFIGURATION"][key] = value.replace(place_holder, setting_workflow)
126
+ if isinstance(value, list):
127
+ config["CONFIGURATION"][key] = [
128
+ item.replace(place_holder, setting_workflow) for item in value
129
+ ]
130
+ config["CONFIGURATION"]["USE_PLAIN_OUTPUT_PATH"] = True
131
+ config["OUTPUT_PATH"] = output_path
132
+
133
+ return configurations, log_file
134
+
135
+
136
+ def main(): # noqa: D103
137
+ args_dict, _ = _parse(
138
+ Path(__file__).stem,
139
+ description="Run simtools applications from configuration file.",
140
+ usage="simtools-run-application --config_file config_file_name",
141
+ )
142
+ logger = logging.getLogger()
143
+ logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
144
+
145
+ configurations, log_file = read_application_configuration(
146
+ args_dict["configuration_file"], logger
147
+ )
148
+
149
+ with log_file.open("w", encoding="utf-8") as file:
150
+ file.write("Running simtools applications\n")
151
+ file.write(dependencies.get_version_string())
152
+ for config in configurations:
153
+ logger.info(f"Running application: {config.get('APPLICATION')}")
154
+ config = gen.change_dict_keys_case(config, False)
155
+ stdout, stderr = run_application(
156
+ config.get("APPLICATION"), config.get("CONFIGURATION"), logger
157
+ )
158
+ file.write("=" * 80 + "\n")
159
+ file.write(f"Application: {config.get('APPLICATION')}\n")
160
+ file.write("STDOUT:\n" + stdout)
161
+ file.write("STDERR:\n" + stderr)
162
+
163
+
164
+ if __name__ == "__main__":
165
+ main()
@@ -117,7 +117,6 @@ r"""
117
117
 
118
118
  """
119
119
 
120
-
121
120
  import logging
122
121
  import subprocess
123
122
  from pathlib import Path
@@ -390,7 +389,6 @@ def main():
390
389
  run_script = light_source.prepare_script(generate_postscript=True, **args_dict)
391
390
  log_file = f"{light_source.output_directory}/logfile.log"
392
391
  with open(log_file, "w", encoding="utf-8") as log_file:
393
-
394
392
  subprocess.run(
395
393
  run_script,
396
394
  shell=False,
@@ -430,7 +428,6 @@ def main():
430
428
  )
431
429
 
432
430
  elif args_dict["light_source_setup"] == "layout":
433
-
434
431
  light_source = SimulatorLightEmission(
435
432
  telescope_model=telescope_model,
436
433
  calibration_model=calibration_model,
@@ -443,7 +440,6 @@ def main():
443
440
  run_script = light_source.prepare_script(generate_postscript=True, **args_dict)
444
441
  log_file = f"{light_source.output_directory}/logfile.log"
445
442
  with open(log_file, "w", encoding="utf-8") as log_file:
446
-
447
443
  subprocess.run(
448
444
  run_script, shell=False, check=False, text=True, stdout=log_file, stderr=log_file
449
445
  )
@@ -31,7 +31,7 @@ r"""
31
31
  Zenith angle in degrees.
32
32
  nshow (int, optional)
33
33
  Number of showers to simulate.
34
- The Number of simulated events depends on the number of times a shower is re-used in the
34
+ The Number of simulated events depends on the number of times a shower is reused in the
35
35
  telescope simulation. The number provided here is before any reuse factors.
36
36
  start_run (int, required)
37
37
  Start run number such that the actual run number will be 'start_run' + 'run'.
@@ -1,40 +1,40 @@
1
1
  #!/usr/bin/python3
2
2
 
3
3
  r"""
4
- Generate a run script and submit file for HT Condor job submission of a simulation production.
4
+ Generate a run script and submit file for HT Condor job submission of a simulation production.
5
5
 
6
- This tool facilitates the submission of multiple simulations to the HT Condor batch system,
7
- enabling:
6
+ This tool facilitates the submission of multiple simulations to the HT Condor batch system,
7
+ enabling:
8
8
 
9
- - Execution of simulations using the "simtools-simulate-prod" application.
10
- - 'number_of_runs' jobs are submitted to the HT Condor batch system.
11
- - Utilization of an Apptainer image containing the SimPipe simulation software and tools.
12
- - Packaging of data and histogram files, and writing them to a specified directory.
9
+ - Execution of simulations using the "simtools-simulate-prod" application.
10
+ - 'number_of_runs' jobs are submitted to the HT Condor batch system.
11
+ - Utilization of an Apptainer image containing the SimPipe simulation software and tools.
12
+ - Packaging of data and histogram files, and writing them to a specified directory.
13
13
 
14
- This tool is intended for use in an HT Condor environment. Jobs run in a container universe
15
- using the Apptainer image specified in the command line ('--apptainer_image'). Output is written
16
- to the 'output_path' directory, with 'simtools-output' and 'logs' subdirectories.
14
+ This tool is intended for use in an HT Condor environment. Jobs run in a container universe
15
+ using the Apptainer image specified in the command line ('--apptainer_image'). Output is written
16
+ to the 'output_path' directory, with 'simtools-output' and 'logs' subdirectories.
17
17
 
18
- Requirements for the 'simtools-simulate-prod-htcondor-generator' application:
18
+ Requirements for the 'simtools-simulate-prod-htcondor-generator' application:
19
19
 
20
- - Availability of an Apptainer image 'simtools-prod' (obtainable from the package registry on
21
- GitHub, e.g., via 'apptainer pull --force docker://ghcr.io/gammasim/simtools-prod:latest').
22
- - Environment parameters required to run CORSIKA and sim_telarray, as well as DB access
23
- credentials. These should be listed similarly to a '.env' file and copied to
24
- 'output_path/env.txt'. Ensure that the path to the simulation software is correctly set to
25
- 'SIMTOOLS_SIMTEL_PATH=/workdir/sim_telarray'.
20
+ - Availability of an Apptainer image 'simtools-prod' (obtainable from the package registry on
21
+ GitHub, e.g., via 'apptainer pull --force docker://ghcr.io/gammasim/simtools-prod:latest').
22
+ - Environment parameters required to run CORSIKA and sim_telarray, as well as DB access
23
+ credentials. These should be listed similarly to a '.env' file and copied to
24
+ 'output_path/env.txt'. Ensure that the path to the simulation software is correctly set to
25
+ 'SIMTOOLS_SIMTEL_PATH=/workdir/sim_telarray'.
26
26
 
27
27
 
28
- Command line arguments
29
- ----------------------
30
- output_path (str, required)
31
- Directory where the output and the simulation data files will be written.
32
- apptainer_image (str, optional)
33
- Apptainer image to use for the simulation (full path).
34
- priority (int, optional)
35
- Job priority (default: 1).
28
+ Command line arguments
29
+ ----------------------
30
+ output_path (str, required)
31
+ Directory where the output and the simulation data files will be written.
32
+ apptainer_image (str, optional)
33
+ Apptainer image to use for the simulation (full path).
34
+ priority (int, optional)
35
+ Job priority (default: 1).
36
36
 
37
- (all other command line arguments are identical to those of :ref:`simulate_prod`).
37
+ (all other command line arguments are identical to those of :ref:`simulate_prod`).
38
38
 
39
39
  """
40
40
 
@@ -24,7 +24,7 @@ r"""
24
24
  simtools-submit-data-from-external \\
25
25
  --input_meta ./tests/resources/MLTdata-preproduction.meta.yml \\
26
26
  --input ./tests/resources/MLTdata-preproduction.ecsv \\
27
- --schema ./tests/resources/schema_MST_mirror_2f_measurements.yml \\
27
+ --schema src/simtools/schemas/input/MST_mirror_2f_measurements.schema.yml \\
28
28
  --output_file TEST-submit_data_from_external.ecsv
29
29
 
30
30
  Expected final print-out message:
@@ -83,6 +83,12 @@ def _parse(label, description):
83
83
  type=str,
84
84
  required=False,
85
85
  )
86
+ config.parser.add_argument(
87
+ "--ignore_metadata",
88
+ help="Ignore metadata",
89
+ action="store_true",
90
+ required=False,
91
+ )
86
92
  return config.initialize(output=True)
87
93
 
88
94
 
@@ -95,16 +101,18 @@ def main(): # noqa: D103
95
101
  logger = logging.getLogger()
96
102
  logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
97
103
 
98
- _metadata = MetadataCollector(args_dict=args_dict)
104
+ _metadata = None if args_dict.get("ignore_metadata") else MetadataCollector(args_dict)
99
105
 
100
106
  data_validator = validate_data.DataValidator(
101
- schema_file=_metadata.get_data_model_schema_file_name(),
107
+ schema_file=(
108
+ _metadata.get_data_model_schema_file_name() if _metadata else args_dict.get("schema")
109
+ ),
102
110
  data_file=args_dict["input"],
103
111
  )
104
112
 
105
113
  writer.ModelDataWriter.dump(
106
114
  args_dict=args_dict,
107
- metadata=_metadata.get_top_level_metadata(),
115
+ metadata=_metadata.get_top_level_metadata() if _metadata else None,
108
116
  product_data=data_validator.validate_and_transform(),
109
117
  )
110
118
 
@@ -16,8 +16,8 @@ r"""
16
16
  instrument name.
17
17
  site (str)
18
18
  site location.
19
- model_version (str)
20
- Model version.
19
+ parameter_version (str)
20
+ Parameter version.
21
21
  input_meta (str, optional)
22
22
  input meta data file (yml format)
23
23
 
@@ -33,7 +33,7 @@ r"""
33
33
  --value 2 \\
34
34
  --instrument LSTN-design \\
35
35
  --site North \\
36
- --model_version 6.0.0 \\
36
+ --parameter_version 0.1.0 \\
37
37
  --input_meta num_gains.metadata.yml
38
38
 
39
39
  """
@@ -70,8 +70,9 @@ def _parse(label, description):
70
70
  )
71
71
  config.parser.add_argument("--instrument", type=str, required=True, help="Instrument name")
72
72
  config.parser.add_argument("--site", type=str, required=True, help="Site location")
73
- config.parser.add_argument("--model_version", type=str, required=True, help="Model version")
74
-
73
+ config.parser.add_argument(
74
+ "--parameter_version", type=str, required=True, help="Parameter version"
75
+ )
75
76
  config.parser.add_argument(
76
77
  "--value",
77
78
  type=str,
@@ -82,18 +83,22 @@ def _parse(label, description):
82
83
  'Examples: "--value=5", "--value=\'5 km\'", "--value=\'5 cm, 0.5 deg\'"'
83
84
  ),
84
85
  )
85
-
86
86
  config.parser.add_argument(
87
87
  "--input_meta",
88
88
  help="meta data file associated to input data",
89
89
  type=str,
90
90
  required=False,
91
91
  )
92
- return config.initialize(output=True)
92
+ config.parser.add_argument(
93
+ "--check_parameter_version",
94
+ help="Check if the parameter version exists in the database",
95
+ action="store_true",
96
+ )
97
+ return config.initialize(output=True, db_config=True)
93
98
 
94
99
 
95
100
  def main(): # noqa: D103
96
- args_dict, _ = _parse(
101
+ args_dict, db_config = _parse(
97
102
  label=Path(__file__).stem,
98
103
  description="Submit and validate a model parameters).",
99
104
  )
@@ -102,19 +107,21 @@ def main(): # noqa: D103
102
107
  logger.setLevel(gen.get_log_level_from_user(args_dict["log_level"]))
103
108
 
104
109
  output_path = (
105
- Path(args_dict["output_path"]) / args_dict["model_version"] / args_dict["instrument"]
110
+ Path(args_dict["output_path"]) / args_dict["instrument"] / args_dict["parameter"]
106
111
  if args_dict.get("output_path")
107
112
  else None
108
113
  )
114
+
109
115
  writer.ModelDataWriter.dump_model_parameter(
110
116
  parameter_name=args_dict["parameter"],
111
117
  value=args_dict["value"],
112
118
  instrument=args_dict["instrument"],
113
- model_version=args_dict["model_version"],
114
- output_file=Path(args_dict["parameter"]).with_suffix(".json"),
119
+ parameter_version=args_dict["parameter_version"],
120
+ output_file=Path(args_dict["parameter"] + "-" + args_dict["parameter_version"] + ".json"),
115
121
  output_path=output_path,
116
122
  use_plain_output_path=args_dict.get("use_plain_output_path"),
117
123
  metadata_input_dict=args_dict,
124
+ db_config=db_config if args_dict.get("check_parameter_version") else None,
118
125
  )
119
126
 
120
127
 
@@ -47,7 +47,7 @@ import logging
47
47
  from pathlib import Path
48
48
 
49
49
  import simtools.utils.general as gen
50
- from simtools.camera_efficiency import CameraEfficiency
50
+ from simtools.camera.camera_efficiency import CameraEfficiency
51
51
  from simtools.configuration import configurator
52
52
 
53
53
 
@@ -106,7 +106,7 @@ def main(): # noqa: D103
106
106
  ce = CameraEfficiency(
107
107
  db_config=_db_config,
108
108
  simtel_path=args_dict["simtel_path"],
109
- label=label,
109
+ label=args_dict.get("label", label),
110
110
  config_data=args_dict,
111
111
  )
112
112
  ce.simulate()