gammasimtools 0.26.0__py3-none-any.whl → 0.27.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.
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/METADATA +5 -1
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/RECORD +70 -66
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/entry_points.txt +1 -1
- simtools/_version.py +2 -2
- simtools/applications/convert_geo_coordinates_of_array_elements.py +2 -1
- simtools/applications/db_get_array_layouts_from_db.py +1 -1
- simtools/applications/{calculate_incident_angles.py → derive_incident_angle.py} +16 -16
- simtools/applications/derive_mirror_rnda.py +111 -177
- simtools/applications/generate_corsika_histograms.py +38 -1
- simtools/applications/generate_regular_arrays.py +73 -36
- simtools/applications/simulate_flasher.py +3 -13
- simtools/applications/simulate_illuminator.py +2 -10
- simtools/applications/simulate_pedestals.py +1 -1
- simtools/applications/simulate_prod.py +8 -7
- simtools/applications/submit_data_from_external.py +2 -1
- simtools/applications/validate_camera_efficiency.py +28 -27
- simtools/applications/validate_cumulative_psf.py +1 -3
- simtools/applications/validate_optics.py +2 -1
- simtools/atmosphere.py +83 -0
- simtools/camera/camera_efficiency.py +171 -48
- simtools/camera/single_photon_electron_spectrum.py +6 -6
- simtools/configuration/commandline_parser.py +47 -9
- simtools/constants.py +5 -0
- simtools/corsika/corsika_config.py +88 -185
- simtools/corsika/corsika_histograms.py +246 -69
- simtools/data_model/model_data_writer.py +46 -49
- simtools/data_model/schema.py +2 -0
- simtools/db/db_handler.py +4 -2
- simtools/db/mongo_db.py +2 -2
- simtools/io/ascii_handler.py +51 -3
- simtools/io/io_handler.py +23 -12
- simtools/job_execution/job_manager.py +154 -79
- simtools/job_execution/process_pool.py +137 -0
- simtools/layout/array_layout.py +0 -1
- simtools/layout/array_layout_utils.py +143 -21
- simtools/model/array_model.py +22 -50
- simtools/model/calibration_model.py +4 -4
- simtools/model/model_parameter.py +123 -73
- simtools/model/model_utils.py +40 -1
- simtools/model/site_model.py +4 -4
- simtools/model/telescope_model.py +4 -5
- simtools/ray_tracing/incident_angles.py +87 -6
- simtools/ray_tracing/mirror_panel_psf.py +337 -217
- simtools/ray_tracing/psf_analysis.py +57 -42
- simtools/ray_tracing/psf_parameter_optimisation.py +3 -2
- simtools/ray_tracing/ray_tracing.py +37 -10
- simtools/runners/corsika_runner.py +52 -191
- simtools/runners/corsika_simtel_runner.py +74 -100
- simtools/runners/runner_services.py +214 -213
- simtools/runners/simtel_runner.py +27 -155
- simtools/runners/simtools_runner.py +9 -69
- simtools/schemas/application_workflow.metaschema.yml +8 -0
- simtools/settings.py +19 -0
- simtools/simtel/simtel_config_writer.py +0 -55
- simtools/simtel/simtel_seeds.py +184 -0
- simtools/simtel/simulator_array.py +115 -103
- simtools/simtel/simulator_camera_efficiency.py +66 -42
- simtools/simtel/simulator_light_emission.py +110 -123
- simtools/simtel/simulator_ray_tracing.py +78 -63
- simtools/simulator.py +135 -346
- simtools/testing/sim_telarray_metadata.py +13 -11
- simtools/testing/validate_output.py +87 -19
- simtools/utils/general.py +6 -17
- simtools/utils/random.py +36 -0
- simtools/visualization/plot_corsika_histograms.py +2 -0
- simtools/visualization/plot_incident_angles.py +48 -1
- simtools/visualization/plot_psf.py +160 -18
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/licenses/LICENSE +0 -0
- {gammasimtools-0.26.0.dist-info → gammasimtools-0.27.0.dist-info}/top_level.txt +0 -0
|
@@ -1,227 +1,161 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
2
|
|
|
3
|
-
r"""
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Command line arguments
|
|
65
|
-
----------------------
|
|
66
|
-
telescope (str, required)
|
|
67
|
-
Telescope name (e.g. LSTN-01, SSTS-25)
|
|
68
|
-
model_version (str, optional)
|
|
69
|
-
Model version
|
|
70
|
-
psf_measurement (str, optional)
|
|
71
|
-
Table with results from PSF measurements for each mirror panel spot size
|
|
72
|
-
psf_measurement_containment_mean (float, required)
|
|
73
|
-
Mean of measured containment diameter [cm]
|
|
74
|
-
psf_measurement_containment_sigma (float, optional)
|
|
75
|
-
Std dev of measured containment diameter [cm]
|
|
76
|
-
containment_fraction (float, required)
|
|
77
|
-
Containment fraction for diameter calculation
|
|
78
|
-
rnda (float, optional)
|
|
79
|
-
Starting value of mirror_reflection_random_angle [deg]. If not given, the value from the
|
|
80
|
-
default model is read from the simulation model database.
|
|
81
|
-
mirror_list (file, optional)
|
|
82
|
-
Table with mirror ID and panel radius.
|
|
83
|
-
use_random_focal_length (activation mode, optional)
|
|
84
|
-
Use random focal lengths, instead of the measured ones. The argument random_focal_length
|
|
85
|
-
can be used to replace the default random_focal_length from the model.
|
|
86
|
-
random_focal_length (float, optional)
|
|
87
|
-
Value of the random focal lengths to replace the default random_focal_length. Only used if
|
|
88
|
-
'use_random_focal_length' is activated.
|
|
89
|
-
random_focal_length_seed (int, optional)
|
|
90
|
-
Seed for the random number generator used for focal length variation.
|
|
91
|
-
no_tuning (activation mode, optional)
|
|
92
|
-
Turn off the tuning - A single case will be simulated and plotted.
|
|
93
|
-
test (activation mode, optional)
|
|
94
|
-
If activated, application will be faster by simulating only few mirrors.
|
|
95
|
-
|
|
96
|
-
Example
|
|
97
|
-
-------
|
|
98
|
-
Derive mirror random reflection angle for a large-sized telescope (LSTS),
|
|
99
|
-
simulation production 6.0.0
|
|
100
|
-
|
|
101
|
-
.. code-block:: console
|
|
102
|
-
|
|
103
|
-
simtools-derive-mirror-rnda \\
|
|
104
|
-
--site South \\
|
|
105
|
-
--telescope LSTS-design \\
|
|
106
|
-
--model_version 6.0.0 \\
|
|
107
|
-
--containment_fraction 0.8 \\
|
|
108
|
-
--mirror_list ./tests/resources/mirror_list_CTA-N-LST1_v2019-03-31_rotated.ecsv
|
|
109
|
-
--rnda 0.003 \\
|
|
110
|
-
--psf_measurement_containment_mean 1.4 \\
|
|
111
|
-
|
|
112
|
-
Expected final print-out message:
|
|
113
|
-
|
|
114
|
-
.. code-block:: console
|
|
115
|
-
|
|
116
|
-
Measured D80:
|
|
117
|
-
Mean = 1.400 cm
|
|
118
|
-
|
|
119
|
-
Simulated D80:
|
|
120
|
-
Mean = 1.406 cm, StdDev = 0.005 cm
|
|
121
|
-
|
|
122
|
-
mirror_random_reflection_angle
|
|
123
|
-
Previous value = 0.003000
|
|
124
|
-
New value = 0.003824
|
|
3
|
+
r"""Derive mirror random reflection angle based on per-mirror PSF diameter optimization.
|
|
4
|
+
|
|
5
|
+
Description
|
|
6
|
+
-----------
|
|
7
|
+
|
|
8
|
+
This application derives the value of the simulation model parameter
|
|
9
|
+
*mirror_reflection_random_angle* using measurements of a PSF containment diameter
|
|
10
|
+
and focal length of individual mirror panels.
|
|
11
|
+
|
|
12
|
+
The optimization uses percentage difference as the metric::
|
|
13
|
+
|
|
14
|
+
pct_diff = 100 * (simulated_psf - measured_psf) / measured_psf
|
|
15
|
+
|
|
16
|
+
Each mirror is optimized individually, and the final RNDA is the average of all
|
|
17
|
+
per-mirror optimized values.
|
|
18
|
+
|
|
19
|
+
Command line arguments
|
|
20
|
+
----------------------
|
|
21
|
+
|
|
22
|
+
site (str, required)
|
|
23
|
+
North or South.
|
|
24
|
+
telescope (str, required)
|
|
25
|
+
Telescope name (e.g. LSTN-01, SSTS-25).
|
|
26
|
+
model_version (str, optional)
|
|
27
|
+
Model version.
|
|
28
|
+
data (str, required)
|
|
29
|
+
ECSV file with PSF diameter (mm) per mirror.
|
|
30
|
+
Accepted column names: psf_opt, psf, or d80.
|
|
31
|
+
fraction (float, optional)
|
|
32
|
+
PSF containment fraction for diameter calculation (e.g. 0.8 for D80, 0.95 for D95).
|
|
33
|
+
Default: 0.8.
|
|
34
|
+
threshold (float, optional)
|
|
35
|
+
Convergence threshold for percentage difference (e.g. 0.05 for 5%).
|
|
36
|
+
Default: 0.05.
|
|
37
|
+
learning_rate (float, optional)
|
|
38
|
+
Learning rate for gradient descent. Default: 0.001.
|
|
39
|
+
test (optional)
|
|
40
|
+
Only optimize a small number of mirrors.
|
|
41
|
+
n_workers (int, optional)
|
|
42
|
+
Number of parallel worker processes to use. Default: 0 (auto chooses maximum).
|
|
43
|
+
number_of_mirrors_to_test (int, optional)
|
|
44
|
+
Number of mirrors to optimize when --test is used. Default: 10.
|
|
45
|
+
psf_hist (str, optional)
|
|
46
|
+
If activated, write a histogram comparing measured vs simulated PSF diameter distributions.
|
|
47
|
+
cleanup (optional)
|
|
48
|
+
Remove intermediate files (patterns: ``*.log``, ``*.lis*``, ``*.dat``)
|
|
49
|
+
from output.
|
|
50
|
+
|
|
51
|
+
Example
|
|
52
|
+
-------
|
|
53
|
+
|
|
54
|
+
.. code-block:: console
|
|
55
|
+
|
|
56
|
+
simtools-derive-mirror-rnda \
|
|
57
|
+
--site North \
|
|
58
|
+
--telescope LSTN-01 \
|
|
59
|
+
--model_version 7.0.0 \
|
|
60
|
+
--data tests/resources/MLTdata-preproduction.ecsv \
|
|
61
|
+
--parameter_version 1.0.0 \
|
|
62
|
+
--test --psf_hist --cleanup
|
|
125
63
|
|
|
126
64
|
"""
|
|
127
65
|
|
|
66
|
+
from pathlib import Path
|
|
67
|
+
|
|
128
68
|
from simtools.application_control import get_application_label, startup_application
|
|
129
69
|
from simtools.configuration import configurator
|
|
130
70
|
from simtools.ray_tracing.mirror_panel_psf import MirrorPanelPSF
|
|
71
|
+
from simtools.ray_tracing.psf_parameter_optimisation import cleanup_intermediate_files
|
|
131
72
|
|
|
132
73
|
|
|
133
74
|
def _parse():
|
|
134
75
|
"""Parse command line configuration."""
|
|
135
76
|
config = configurator.Configurator(
|
|
136
|
-
description="Derive mirror
|
|
77
|
+
description="Derive mirror RNDA using per-mirror PSF diameter optimization.",
|
|
78
|
+
label=get_application_label(__file__),
|
|
137
79
|
)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
"
|
|
141
|
-
help="Mean of measured PSF containment diameter [cm]",
|
|
142
|
-
type=float,
|
|
143
|
-
required=False,
|
|
144
|
-
)
|
|
145
|
-
psf_group.add_argument(
|
|
146
|
-
"--psf_measurement",
|
|
147
|
-
help="Results from PSF measurements for each mirror panel spot size",
|
|
80
|
+
config.parser.add_argument(
|
|
81
|
+
"--data",
|
|
82
|
+
help="ECSV file with a PSF diameter column (mm) per mirror",
|
|
148
83
|
type=str,
|
|
149
|
-
required=
|
|
84
|
+
required=True,
|
|
150
85
|
)
|
|
151
86
|
config.parser.add_argument(
|
|
152
|
-
"--
|
|
153
|
-
help="
|
|
87
|
+
"--threshold",
|
|
88
|
+
help="Convergence threshold for percentage difference.",
|
|
154
89
|
type=float,
|
|
155
90
|
required=False,
|
|
91
|
+
default=0.05,
|
|
156
92
|
)
|
|
157
93
|
config.parser.add_argument(
|
|
158
|
-
"--
|
|
159
|
-
help="
|
|
160
|
-
type=config.parser.efficiency_interval,
|
|
161
|
-
required=False,
|
|
162
|
-
default=0.8,
|
|
163
|
-
)
|
|
164
|
-
config.parser.add_argument(
|
|
165
|
-
"--rnda",
|
|
166
|
-
help="Starting value of mirror_reflection_random_angle",
|
|
94
|
+
"--learning_rate",
|
|
95
|
+
help="Learning rate for gradient descent.",
|
|
167
96
|
type=float,
|
|
168
97
|
required=False,
|
|
169
|
-
default=0.
|
|
170
|
-
)
|
|
171
|
-
config.parser.add_argument(
|
|
172
|
-
"--mirror_list",
|
|
173
|
-
help=("Mirror list file to replace the default one."),
|
|
174
|
-
type=str,
|
|
175
|
-
required=False,
|
|
98
|
+
default=0.001,
|
|
176
99
|
)
|
|
177
100
|
config.parser.add_argument(
|
|
178
|
-
"--
|
|
179
|
-
help=
|
|
101
|
+
"--fraction",
|
|
102
|
+
help=(
|
|
103
|
+
"PSF containment fraction for diameter calculation (e.g., 0.8 for D80, 0.95 for D95)."
|
|
104
|
+
),
|
|
180
105
|
type=float,
|
|
181
|
-
|
|
182
|
-
default=0.1,
|
|
106
|
+
default=0.8,
|
|
183
107
|
)
|
|
184
108
|
config.parser.add_argument(
|
|
185
|
-
"--
|
|
186
|
-
help=
|
|
187
|
-
|
|
109
|
+
"--n_workers",
|
|
110
|
+
help="Number of parallel worker processes to use.",
|
|
111
|
+
type=int,
|
|
188
112
|
required=False,
|
|
113
|
+
default=0,
|
|
189
114
|
)
|
|
190
115
|
config.parser.add_argument(
|
|
191
|
-
"--
|
|
192
|
-
help=
|
|
193
|
-
|
|
194
|
-
),
|
|
195
|
-
default=None,
|
|
196
|
-
type=float,
|
|
116
|
+
"--number_of_mirrors_to_test",
|
|
117
|
+
help="Number of mirrors to optimize when --test is used.",
|
|
118
|
+
type=int,
|
|
197
119
|
required=False,
|
|
120
|
+
default=10,
|
|
198
121
|
)
|
|
199
122
|
config.parser.add_argument(
|
|
200
|
-
"--
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
required=False,
|
|
123
|
+
"--psf_hist",
|
|
124
|
+
nargs="?",
|
|
125
|
+
const="psf_distributions.png",
|
|
204
126
|
default=None,
|
|
127
|
+
help=(
|
|
128
|
+
"Write a histogram comparing measured vs simulated PSF diameter distributions. "
|
|
129
|
+
"Optionally provide a filename (relative to output dir unless absolute)."
|
|
130
|
+
),
|
|
205
131
|
)
|
|
206
132
|
config.parser.add_argument(
|
|
207
|
-
"--
|
|
208
|
-
help="no tuning of random_reflection_angle (a single case will be simulated).",
|
|
133
|
+
"--cleanup",
|
|
209
134
|
action="store_true",
|
|
210
|
-
|
|
135
|
+
default=False,
|
|
136
|
+
help=(
|
|
137
|
+
"Remove intermediate files from the output directory (patterns: *.log, *.lis*, *.dat)."
|
|
138
|
+
),
|
|
211
139
|
)
|
|
212
140
|
return config.initialize(
|
|
213
|
-
db_config=True,
|
|
141
|
+
db_config=True,
|
|
142
|
+
output=True,
|
|
143
|
+
simulation_model=["telescope", "model_version", "site", "parameter_version"],
|
|
214
144
|
)
|
|
215
145
|
|
|
216
146
|
|
|
217
147
|
def main():
|
|
218
|
-
"""Derive mirror random reflection angle
|
|
148
|
+
"""Derive mirror random reflection angle using per-mirror PSF diameter optimization."""
|
|
219
149
|
app_context = startup_application(_parse)
|
|
220
|
-
|
|
221
150
|
panel_psf = MirrorPanelPSF(app_context.args.get("label"), app_context.args)
|
|
222
|
-
panel_psf.
|
|
223
|
-
panel_psf.print_results()
|
|
151
|
+
panel_psf.optimize_with_gradient_descent()
|
|
224
152
|
panel_psf.write_optimization_data()
|
|
153
|
+
if app_context.args.get("psf_hist"):
|
|
154
|
+
panel_psf.write_psf_histogram()
|
|
155
|
+
|
|
156
|
+
if app_context.args.get("cleanup"):
|
|
157
|
+
output_dir = Path(app_context.args.get("output_path", "."))
|
|
158
|
+
cleanup_intermediate_files(output_dir)
|
|
225
159
|
|
|
226
160
|
|
|
227
161
|
if __name__ == "__main__":
|
|
@@ -50,8 +50,25 @@ r"""
|
|
|
50
50
|
--file_lablels label1 label2 \\
|
|
51
51
|
--pdf_file_name test.pdf
|
|
52
52
|
|
|
53
|
+
Notes
|
|
54
|
+
-----
|
|
55
|
+
The typical use case of this application is to generate lateral photon density distribution
|
|
56
|
+
to compare different CORSIKA simulation settings or different CORSIKA versions. The following
|
|
57
|
+
steps are recommended:
|
|
58
|
+
|
|
59
|
+
- generate a 'star'-like array of telescopes with the 'simtools-generate-regular-arrays'
|
|
60
|
+
application. There should be a sufficient number of telescopes (e.g. 50 or more) in the
|
|
61
|
+
layout with non-overlapping telescope definitions
|
|
62
|
+
|
|
63
|
+
- run CORSIKA simulations with the desired settings using this telescope layout (use the
|
|
64
|
+
'overwrite_model_parameters' option to point to the generated layout simulation model
|
|
65
|
+
change file (in the format given by 'simulation_models_info.schema.yml').
|
|
66
|
+
|
|
67
|
+
- run this application to generate the histograms for the produced CORSIKA IACT output
|
|
53
68
|
"""
|
|
54
69
|
|
|
70
|
+
from astropy import units as u
|
|
71
|
+
|
|
55
72
|
from simtools.application_control import get_application_label, startup_application
|
|
56
73
|
from simtools.configuration import configurator
|
|
57
74
|
from simtools.corsika.corsika_histograms import CorsikaHistograms
|
|
@@ -78,6 +95,22 @@ def _parse():
|
|
|
78
95
|
nargs="+",
|
|
79
96
|
required=None,
|
|
80
97
|
)
|
|
98
|
+
config.parser.add_argument(
|
|
99
|
+
"--normalization",
|
|
100
|
+
help="Normalization method for histograms. Options: 'per-telescope', 'per-bin'",
|
|
101
|
+
type=str,
|
|
102
|
+
choices=["per-telescope", "per-bin"],
|
|
103
|
+
default="per-telescope",
|
|
104
|
+
)
|
|
105
|
+
config.parser.add_argument(
|
|
106
|
+
"--axis_distance",
|
|
107
|
+
help=(
|
|
108
|
+
"Distance from x/y axes to consider when calculating "
|
|
109
|
+
"the lateral density profiles (in meters)."
|
|
110
|
+
),
|
|
111
|
+
type=float,
|
|
112
|
+
default=1000.0,
|
|
113
|
+
)
|
|
81
114
|
config.parser.add_argument(
|
|
82
115
|
"--pdf_file_name",
|
|
83
116
|
help="Save histograms into a pdf file.",
|
|
@@ -93,7 +126,11 @@ def main():
|
|
|
93
126
|
|
|
94
127
|
all_histograms = []
|
|
95
128
|
for input_file in app_context.args["input_files"]:
|
|
96
|
-
corsika_histograms = CorsikaHistograms(
|
|
129
|
+
corsika_histograms = CorsikaHistograms(
|
|
130
|
+
input_file,
|
|
131
|
+
normalization_method=app_context.args["normalization"],
|
|
132
|
+
axis_distance=app_context.args["axis_distance"] * u.m,
|
|
133
|
+
)
|
|
97
134
|
corsika_histograms.fill()
|
|
98
135
|
all_histograms.append(corsika_histograms)
|
|
99
136
|
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
2
|
|
|
3
3
|
"""
|
|
4
|
-
Make a regular array of telescopes and save it
|
|
4
|
+
Make a regular array of telescopes and save it to file.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
Arrays can consist of single (central) telescopes, square grids or star-like (with
|
|
7
|
+
telescopes arranged on main axes) patterns. All telescopes in the array are of
|
|
8
|
+
the same type and are placed at regular distances.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
Output files are saved as astropy tables in ASCII ECSV format and in the simtools format
|
|
11
|
+
required to be used for the overwrite model parameter configuration.
|
|
10
12
|
|
|
11
13
|
Command line arguments
|
|
12
14
|
----------------------
|
|
15
|
+
telescope_type (str)
|
|
16
|
+
Type of telescope (e.g., LST, MST, SST).
|
|
17
|
+
n_telescopes (int)
|
|
18
|
+
Number of telescopes in the array.
|
|
19
|
+
telescope_distance (float)
|
|
20
|
+
Distance between telescopes in the array (in meters).
|
|
21
|
+
array_shape (str)
|
|
22
|
+
Shape of the array ('square', 'star').
|
|
13
23
|
site (str, required)
|
|
14
24
|
observatory site (e.g., North or South).
|
|
15
25
|
model_version (str, optional)
|
|
@@ -31,23 +41,38 @@ import astropy.units as u
|
|
|
31
41
|
import simtools.data_model.model_data_writer as writer
|
|
32
42
|
from simtools.application_control import get_application_label, startup_application
|
|
33
43
|
from simtools.configuration import configurator
|
|
34
|
-
from simtools.layout.array_layout_utils import create_regular_array
|
|
35
|
-
|
|
36
|
-
# Telescope distances for 4 tel square arrays
|
|
37
|
-
# !HARDCODED
|
|
38
|
-
telescope_distance = {"LST": 57.5 * u.m, "MST": 70 * u.m, "SST": 80 * u.m}
|
|
44
|
+
from simtools.layout.array_layout_utils import create_regular_array, write_array_elements_info_yaml
|
|
39
45
|
|
|
40
46
|
|
|
41
47
|
def _parse():
|
|
42
48
|
config = configurator.Configurator(
|
|
43
49
|
label=get_application_label(__file__),
|
|
44
|
-
description=(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
description=("Generate a regular array of telescope and save as astropy table."),
|
|
51
|
+
)
|
|
52
|
+
config.parser.add_argument(
|
|
53
|
+
"--telescope_type",
|
|
54
|
+
help="Type of telescope (e.g., LST, MST, SST).",
|
|
55
|
+
type=str,
|
|
56
|
+
default="LST",
|
|
57
|
+
)
|
|
58
|
+
config.parser.add_argument(
|
|
59
|
+
"--n_telescopes",
|
|
60
|
+
help="Number of telescopes in the array.",
|
|
61
|
+
type=int,
|
|
62
|
+
default=4,
|
|
63
|
+
)
|
|
64
|
+
config.parser.add_argument(
|
|
65
|
+
"--telescope_distance",
|
|
66
|
+
help="Distance between telescopes in the array (in meters).",
|
|
67
|
+
type=float,
|
|
68
|
+
default=50.0,
|
|
69
|
+
)
|
|
70
|
+
config.parser.add_argument(
|
|
71
|
+
"--array_shape",
|
|
72
|
+
help="Shape of the array (e.g., 'square', 'star').",
|
|
73
|
+
type=str,
|
|
74
|
+
default="square",
|
|
75
|
+
choices=["square", "star"],
|
|
51
76
|
)
|
|
52
77
|
return config.initialize(
|
|
53
78
|
db_config=False, simulation_model=["site", "model_version"], output=True
|
|
@@ -55,32 +80,44 @@ def _parse():
|
|
|
55
80
|
|
|
56
81
|
|
|
57
82
|
def main():
|
|
58
|
-
"""Create layout array files
|
|
83
|
+
"""Create layout array files of regular arrays."""
|
|
59
84
|
app_context = startup_application(_parse)
|
|
60
85
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
n_tel = app_context.args["n_telescopes"]
|
|
87
|
+
tel_type = app_context.args["telescope_type"]
|
|
88
|
+
tel_dist = app_context.args["telescope_distance"] * u.m
|
|
89
|
+
shape = app_context.args["array_shape"]
|
|
90
|
+
|
|
91
|
+
array_name = f"{n_tel}{tel_type}-{shape}"
|
|
92
|
+
app_context.logger.info(f"Processing array {array_name}")
|
|
93
|
+
|
|
94
|
+
array_table = create_regular_array(
|
|
95
|
+
array_name,
|
|
96
|
+
app_context.args["site"],
|
|
97
|
+
n_telescopes=n_tel,
|
|
98
|
+
telescope_type=tel_type,
|
|
99
|
+
telescope_distance=tel_dist,
|
|
100
|
+
shape=shape,
|
|
101
|
+
)
|
|
68
102
|
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
output_file = app_context.args.get("output_file")
|
|
104
|
+
if output_file:
|
|
105
|
+
output_path = Path(output_file)
|
|
106
|
+
output_file = output_path.with_name(
|
|
107
|
+
f"{output_path.stem}-{app_context.args['site']}-{array_name}{output_path.suffix}"
|
|
71
108
|
)
|
|
72
109
|
|
|
73
|
-
|
|
74
|
-
if output_file:
|
|
75
|
-
output_path = Path(output_file)
|
|
76
|
-
output_file = output_path.with_name(
|
|
77
|
-
f"{output_path.stem}-{app_context.args['site']}-{array_name}{output_path.suffix}"
|
|
78
|
-
)
|
|
79
|
-
writer.ModelDataWriter.dump(
|
|
80
|
-
args_dict=app_context.args,
|
|
110
|
+
data_writer = writer.ModelDataWriter(
|
|
81
111
|
output_file=output_file,
|
|
82
|
-
|
|
83
|
-
|
|
112
|
+
output_file_format=app_context.args.get("output_file_format", "ascii.ecsv"),
|
|
113
|
+
)
|
|
114
|
+
data_writer.write(metadata=None, product_data=array_table)
|
|
115
|
+
|
|
116
|
+
write_array_elements_info_yaml(
|
|
117
|
+
array_table,
|
|
118
|
+
app_context.args["site"],
|
|
119
|
+
app_context.args["model_version"],
|
|
120
|
+
Path(data_writer.output_file).with_suffix(".info.yml"),
|
|
84
121
|
)
|
|
85
122
|
|
|
86
123
|
|
|
@@ -45,8 +45,6 @@ light_source (str, required)
|
|
|
45
45
|
Calibration light source, e.g., MSFx-FlashCam
|
|
46
46
|
number_of_events (int, optional):
|
|
47
47
|
Number of events to simulate (default: 1).
|
|
48
|
-
output_prefix (str, optional):
|
|
49
|
-
Prefix for output files (default: empty).
|
|
50
48
|
model_version (str, optional)
|
|
51
49
|
Version of the simulation model.
|
|
52
50
|
array_layout_name (str, optional)
|
|
@@ -89,13 +87,6 @@ def _parse():
|
|
|
89
87
|
default=1,
|
|
90
88
|
required=False,
|
|
91
89
|
)
|
|
92
|
-
config.parser.add_argument(
|
|
93
|
-
"--output_prefix",
|
|
94
|
-
help="Prefix for output files",
|
|
95
|
-
type=str,
|
|
96
|
-
default=None,
|
|
97
|
-
required=False,
|
|
98
|
-
)
|
|
99
90
|
return config.initialize(
|
|
100
91
|
db_config=True,
|
|
101
92
|
simulation_model=["site", "layout", "telescope", "model_version"],
|
|
@@ -123,14 +114,13 @@ def main():
|
|
|
123
114
|
label=app_context.args.get("label"),
|
|
124
115
|
)
|
|
125
116
|
elif app_context.args["run_mode"] == "direct_injection":
|
|
126
|
-
light_source = Simulator(
|
|
127
|
-
args_dict=app_context.args,
|
|
128
|
-
label=app_context.args.get("label"),
|
|
129
|
-
)
|
|
117
|
+
light_source = Simulator(label=app_context.args.get("label"))
|
|
130
118
|
else:
|
|
131
119
|
raise ValueError(f"Unsupported run_mode: {app_context.args['run_mode']}")
|
|
132
120
|
|
|
133
121
|
light_source.simulate()
|
|
122
|
+
light_source.verify_simulations()
|
|
123
|
+
|
|
134
124
|
app_context.logger.info("Flasher simulation completed.")
|
|
135
125
|
|
|
136
126
|
|
|
@@ -49,8 +49,6 @@ light_source_position (float, float, float, optional)
|
|
|
49
49
|
m. If not set, the position from the simulation model is used.
|
|
50
50
|
light_source_pointing (float, float, float, optional)
|
|
51
51
|
Light source pointing direction. If not set, the pointing from the simulation model is used.
|
|
52
|
-
output_prefix (str, optional)
|
|
53
|
-
Prefix for output files (default: empty).
|
|
54
52
|
"""
|
|
55
53
|
|
|
56
54
|
from simtools.application_control import get_application_label, startup_application
|
|
@@ -100,13 +98,6 @@ def _parse():
|
|
|
100
98
|
default=1,
|
|
101
99
|
required=False,
|
|
102
100
|
)
|
|
103
|
-
config.parser.add_argument(
|
|
104
|
-
"--output_prefix",
|
|
105
|
-
help="Prefix for output files (default: empty)",
|
|
106
|
-
type=str,
|
|
107
|
-
default=None,
|
|
108
|
-
required=False,
|
|
109
|
-
)
|
|
110
101
|
return config.initialize(
|
|
111
102
|
db_config=True,
|
|
112
103
|
simulation_model=["telescope", "model_version"],
|
|
@@ -119,10 +110,11 @@ def main():
|
|
|
119
110
|
app_context = startup_application(_parse)
|
|
120
111
|
|
|
121
112
|
light_source = SimulatorLightEmission(
|
|
122
|
-
light_emission_config=app_context.args,
|
|
113
|
+
light_emission_config={**app_context.args, "run_mode": "illuminator"},
|
|
123
114
|
label=app_context.args.get("label"),
|
|
124
115
|
)
|
|
125
116
|
light_source.simulate()
|
|
117
|
+
light_source.verify_simulations()
|
|
126
118
|
|
|
127
119
|
|
|
128
120
|
if __name__ == "__main__":
|
|
@@ -108,7 +108,7 @@ def main():
|
|
|
108
108
|
"""Simulate pedestal events."""
|
|
109
109
|
app_context = startup_application(_parse)
|
|
110
110
|
|
|
111
|
-
simulator = Simulator(label=app_context.args.get("label")
|
|
111
|
+
simulator = Simulator(label=app_context.args.get("label"))
|
|
112
112
|
simulator.simulate()
|
|
113
113
|
|
|
114
114
|
|