gammasimtools 0.13.0__py3-none-any.whl → 0.14.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.13.0.dist-info → gammasimtools-0.14.0.dist-info}/METADATA +3 -3
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/RECORD +224 -217
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/WHEEL +1 -1
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/entry_points.txt +3 -1
- simtools/_version.py +2 -2
- simtools/applications/db_add_file_to_db.py +15 -0
- simtools/applications/db_add_value_from_json_to_db.py +18 -1
- simtools/applications/derive_ctao_array_layouts.py +120 -0
- simtools/applications/derive_photon_electron_spectrum.py +29 -1
- simtools/applications/docs_produce_array_element_report.py +41 -16
- simtools/applications/docs_produce_model_parameter_reports.py +28 -8
- simtools/applications/{production_extract_mc_event_data.py → generate_simtel_event_data.py} +12 -20
- simtools/applications/print_version.py +81 -0
- simtools/applications/production_derive_corsika_limits.py +172 -39
- simtools/applications/production_scale_events.py +59 -36
- simtools/applications/run_application.py +41 -11
- simtools/applications/simulate_light_emission.py +115 -247
- simtools/applications/simulate_prod_htcondor_generator.py +2 -2
- simtools/camera/single_photon_electron_spectrum.py +163 -15
- simtools/data_model/model_data_writer.py +7 -6
- simtools/db/db_handler.py +14 -8
- simtools/dependencies.py +38 -3
- simtools/layout/array_layout.py +1 -0
- simtools/layout/ctao_array_layouts.py +172 -0
- simtools/model/array_model.py +3 -4
- simtools/model/model_parameter.py +30 -87
- simtools/production_configuration/derive_corsika_limits.py +222 -154
- simtools/production_configuration/event_scaler.py +2 -2
- simtools/reporting/docs_auto_report_generator.py +217 -0
- simtools/reporting/docs_read_parameters.py +192 -110
- simtools/schemas/application_workflow.metaschema.yml +3 -0
- simtools/schemas/model_parameter.metaschema.yml +13 -0
- simtools/schemas/model_parameter_and_data_schema.metaschema.yml +6 -0
- simtools/schemas/model_parameters/adjust_gain.schema.yml +1 -1
- simtools/schemas/model_parameters/altitude.schema.yml +1 -1
- simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +3 -3
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +3 -3
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +3 -3
- simtools/schemas/model_parameters/array_window.schema.yml +1 -1
- simtools/schemas/model_parameters/asum_clipping.schema.yml +1 -1
- simtools/schemas/model_parameters/asum_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/asum_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/axes_offsets.schema.yml +2 -2
- simtools/schemas/model_parameters/camera_body_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_body_shape.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_config_rotate.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_depth.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_pixels.schema.yml +1 -1
- simtools/schemas/model_parameters/camera_transmission.schema.yml +1 -1
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +1 -1
- simtools/schemas/model_parameters/corsika_observation_level.schema.yml +1 -1
- simtools/schemas/model_parameters/dark_events.schema.yml +1 -1
- simtools/schemas/model_parameters/disc_bins.schema.yml +1 -1
- simtools/schemas/model_parameters/disc_start.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/dish_shape_length.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +2 -2
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +1 -1
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +1 -1
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +5 -5
- simtools/schemas/model_parameters/epsg_code.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_bins.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_max_signal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_max_sum.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_mhz.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_noise.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +1 -1
- simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +1 -1
- simtools/schemas/model_parameters/focal_length.schema.yml +1 -1
- simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +20 -20
- simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/focus_offset.schema.yml +4 -4
- simtools/schemas/model_parameters/gain_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/geomag_horizontal.schema.yml +1 -1
- simtools/schemas/model_parameters/geomag_rotation.schema.yml +1 -1
- simtools/schemas/model_parameters/geomag_vertical.schema.yml +1 -1
- simtools/schemas/model_parameters/hg_lg_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/iobuf_maximum.schema.yml +1 -1
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_events.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_external_trigger.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_var_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/laser_wavelength.schema.yml +1 -1
- simtools/schemas/model_parameters/led_events.schema.yml +1 -1
- simtools/schemas/model_parameters/led_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/led_pulse_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +1 -1
- simtools/schemas/model_parameters/led_var_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +1 -1
- simtools/schemas/model_parameters/min_photons.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +4 -4
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +4 -4
- simtools/schemas/model_parameters/mirror_class.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_focal_length.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +3 -3
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +3 -3
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/muon_mono_threshold.schema.yml +45 -0
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +2 -2
- simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +5 -5
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_reference_value.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +1 -1
- simtools/schemas/model_parameters/nsb_spectrum.schema.yml +2 -2
- simtools/schemas/model_parameters/num_gains.schema.yml +1 -1
- simtools/schemas/model_parameters/pedestal_events.schema.yml +1 -1
- simtools/schemas/model_parameters/photon_delay.schema.yml +1 -1
- simtools/schemas/model_parameters/photons_per_run.schema.yml +1 -1
- simtools/schemas/model_parameters/pixel_cells.schema.yml +1 -1
- simtools/schemas/model_parameters/pixels_parallel.schema.yml +1 -1
- simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_average_gain.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_gain_index.schema.yml +1 -1
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +4 -4
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +7 -3
- simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +20 -20
- simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/qe_variation.schema.yml +1 -1
- simtools/schemas/model_parameters/random_focal_length.schema.yml +2 -2
- simtools/schemas/model_parameters/random_mono_probability.schema.yml +38 -0
- simtools/schemas/model_parameters/reference_point_altitude.schema.yml +1 -1
- simtools/schemas/model_parameters/reference_point_latitude.schema.yml +4 -1
- simtools/schemas/model_parameters/reference_point_longitude.schema.yml +4 -1
- simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +1 -1
- simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +5 -5
- simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +20 -20
- simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +1 -1
- simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +1 -1
- simtools/schemas/model_parameters/stars.schema.yml +36 -0
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +1 -1
- simtools/schemas/model_parameters/tailcut_scale.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_axis_height.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_random_angle.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_random_error.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +1 -1
- simtools/schemas/model_parameters/telescope_transmission.schema.yml +6 -6
- simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +1 -1
- simtools/schemas/model_parameters/teltrig_min_time.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_error.schema.yml +1 -1
- simtools/schemas/model_parameters/transit_time_jitter.schema.yml +1 -1
- simtools/schemas/model_parameters/trigger_current_limit.schema.yml +1 -1
- simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +4 -4
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +1 -1
- simtools/simtel/simtel_config_writer.py +70 -38
- simtools/simtel/simtel_io_event_reader.py +278 -0
- simtools/simtel/simtel_io_event_writer.py +317 -0
- simtools/simtel/simulator_light_emission.py +181 -67
- simtools/simulator.py +2 -2
- simtools/testing/configuration.py +17 -0
- simtools/utils/general.py +33 -7
- simtools/utils/geometry.py +19 -0
- simtools/utils/names.py +7 -1
- simtools/visualization/visualize.py +2 -2
- simtools/production_configuration/extract_mc_event_data.py +0 -253
- simtools/simtel/simtel_io_events.py +0 -265
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info/licenses}/LICENSE +0 -0
- {gammasimtools-0.13.0.dist-info → gammasimtools-0.14.0.dist-info}/top_level.txt +0 -0
- /simtools/schemas/model_parameters/{nsb_skymap.schema.yml → nsb_sky_map.schema.yml} +0 -0
|
@@ -7,7 +7,9 @@ import tempfile
|
|
|
7
7
|
from io import BytesIO
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
|
+
import numpy as np
|
|
10
11
|
from astropy.table import Table
|
|
12
|
+
from scipy.optimize import curve_fit
|
|
11
13
|
|
|
12
14
|
import simtools.data_model.model_data_writer as writer
|
|
13
15
|
from simtools.constants import MODEL_PARAMETER_SCHEMA_URL, SCHEMA_PATH
|
|
@@ -52,8 +54,16 @@ class SinglePhotonElectronSpectrum:
|
|
|
52
54
|
|
|
53
55
|
def derive_single_pe_spectrum(self):
|
|
54
56
|
"""Derive single photon electron spectrum."""
|
|
57
|
+
afterpulse_fitted_spectrum = (
|
|
58
|
+
self.fit_afterpulse_spectrum() if self.args_dict.get("fit_afterpulse") else None
|
|
59
|
+
)
|
|
60
|
+
|
|
55
61
|
if self.args_dict.get("use_norm_spe"):
|
|
56
|
-
return self._derive_spectrum_norm_spe(
|
|
62
|
+
return self._derive_spectrum_norm_spe(
|
|
63
|
+
input_spectrum=self.args_dict["input_spectrum"],
|
|
64
|
+
afterpulse_spectrum=self.args_dict.get("afterpulse_spectrum"),
|
|
65
|
+
afterpulse_fitted_spectrum=afterpulse_fitted_spectrum,
|
|
66
|
+
)
|
|
57
67
|
|
|
58
68
|
raise NotImplementedError(
|
|
59
69
|
"Derivation of single photon electron spectrum using a simtool is not yet implemented."
|
|
@@ -92,10 +102,22 @@ class SinglePhotonElectronSpectrum:
|
|
|
92
102
|
validate_schema_file=None,
|
|
93
103
|
)
|
|
94
104
|
|
|
95
|
-
def _derive_spectrum_norm_spe(
|
|
105
|
+
def _derive_spectrum_norm_spe(
|
|
106
|
+
self, input_spectrum, afterpulse_spectrum, afterpulse_fitted_spectrum
|
|
107
|
+
):
|
|
96
108
|
"""
|
|
97
109
|
Derive single photon electron spectrum using sim_telarray tool 'norm_spe'.
|
|
98
110
|
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
input_spectrum : str
|
|
114
|
+
Input file with amplitude spectrum
|
|
115
|
+
(prompt spectrum only if afterpulse spectrum is given).
|
|
116
|
+
afterpulse_spectrum : str
|
|
117
|
+
Input file with afterpulse spectrum.
|
|
118
|
+
afterpulse_fitted_spectrum : astro.Table
|
|
119
|
+
Fitted afterpulse spectrum data.
|
|
120
|
+
|
|
99
121
|
Returns
|
|
100
122
|
-------
|
|
101
123
|
int
|
|
@@ -107,11 +129,13 @@ class SinglePhotonElectronSpectrum:
|
|
|
107
129
|
If the command execution fails.
|
|
108
130
|
"""
|
|
109
131
|
tmp_input_file = self._get_input_data(
|
|
110
|
-
input_file=
|
|
132
|
+
input_file=input_spectrum,
|
|
133
|
+
input_table=None,
|
|
111
134
|
frequency_column=self.prompt_column,
|
|
112
135
|
)
|
|
113
136
|
tmp_ap_file = self._get_input_data(
|
|
114
|
-
input_file=
|
|
137
|
+
input_file=afterpulse_spectrum,
|
|
138
|
+
input_table=afterpulse_fitted_spectrum,
|
|
115
139
|
frequency_column=self.afterpulse_column,
|
|
116
140
|
)
|
|
117
141
|
|
|
@@ -119,13 +143,14 @@ class SinglePhotonElectronSpectrum:
|
|
|
119
143
|
f"{self.args_dict['simtel_path']}/sim_telarray/bin/norm_spe",
|
|
120
144
|
"-r",
|
|
121
145
|
f"{self.args_dict['step_size']},{self.args_dict['max_amplitude']}",
|
|
122
|
-
tmp_input_file.name,
|
|
123
146
|
]
|
|
124
147
|
if tmp_ap_file:
|
|
125
|
-
command.
|
|
126
|
-
command.
|
|
148
|
+
command.extend(["-a", f"{tmp_ap_file.name}"])
|
|
149
|
+
command.extend(["-s", f"{self.args_dict['scale_afterpulse_spectrum']}"])
|
|
150
|
+
command.extend(["-t", f"{self.args_dict['afterpulse_amplitude_range'][0]}"])
|
|
151
|
+
command.append(tmp_input_file.name)
|
|
127
152
|
|
|
128
|
-
self._logger.
|
|
153
|
+
self._logger.info(f"Running norm_spe command: {' '.join(command)}")
|
|
129
154
|
try:
|
|
130
155
|
result = subprocess.run(command, capture_output=True, text=True, check=True)
|
|
131
156
|
except subprocess.CalledProcessError as exc:
|
|
@@ -142,24 +167,37 @@ class SinglePhotonElectronSpectrum:
|
|
|
142
167
|
self.data = result.stdout
|
|
143
168
|
return result.returncode
|
|
144
169
|
|
|
145
|
-
def _get_input_data(self, input_file, frequency_column):
|
|
170
|
+
def _get_input_data(self, input_file, input_table, frequency_column):
|
|
146
171
|
"""
|
|
147
|
-
Return input data
|
|
172
|
+
Return input data in the format required by the norm_spe tool as temporary file.
|
|
173
|
+
|
|
174
|
+
The norm_spe tool requires the data to be space separated values of the amplitude spectrum,
|
|
175
|
+
with two columns: amplitude and frequency.
|
|
176
|
+
Input is validated using the single_pe_spectrum schema (legacy input is not validated).
|
|
148
177
|
|
|
149
|
-
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
input_file : str
|
|
181
|
+
Input file with amplitude spectrum.
|
|
182
|
+
input_table : astro.Table
|
|
183
|
+
Input table with amplitude spectrum.
|
|
184
|
+
frequency_column : str
|
|
185
|
+
Column name of the frequency data.
|
|
150
186
|
"""
|
|
151
|
-
input_data = ""
|
|
152
187
|
if not input_file:
|
|
153
188
|
return None
|
|
154
189
|
input_file = Path(input_file)
|
|
155
190
|
|
|
156
|
-
|
|
191
|
+
input_data = ""
|
|
192
|
+
if input_file.suffix == ".ecsv" or input_table:
|
|
157
193
|
data_validator = validate_data.DataValidator(
|
|
158
|
-
schema_file=self.input_schema,
|
|
194
|
+
schema_file=self.input_schema,
|
|
195
|
+
data_table=input_table,
|
|
196
|
+
data_file=input_file if input_table is None else None,
|
|
159
197
|
)
|
|
160
198
|
table = data_validator.validate_and_transform()
|
|
161
199
|
input_data = "\n".join(f"{row['amplitude']} {row[frequency_column]}" for row in table)
|
|
162
|
-
else:
|
|
200
|
+
else: # legacy format
|
|
163
201
|
with open(input_file, encoding="utf-8") as f:
|
|
164
202
|
input_data = (
|
|
165
203
|
f.read().replace(",", " ")
|
|
@@ -170,3 +208,113 @@ class SinglePhotonElectronSpectrum:
|
|
|
170
208
|
with tempfile.NamedTemporaryFile(delete=False, mode="w", encoding="utf-8") as tmpfile:
|
|
171
209
|
tmpfile.write(input_data)
|
|
172
210
|
return tmpfile
|
|
211
|
+
|
|
212
|
+
def fit_afterpulse_spectrum(self):
|
|
213
|
+
"""
|
|
214
|
+
Fit afterpulse spectrum with a exponential decay function.
|
|
215
|
+
|
|
216
|
+
Assume input to be in ecsv format with columns 'amplitude', 'frequency (afterpulsing)',
|
|
217
|
+
and 'frequency stdev (afterpulsing)'.
|
|
218
|
+
|
|
219
|
+
Returns
|
|
220
|
+
-------
|
|
221
|
+
astro.Table
|
|
222
|
+
Table with fitted afterpulse spectrum data.
|
|
223
|
+
"""
|
|
224
|
+
ap_min = self.args_dict["afterpulse_amplitude_range"][0]
|
|
225
|
+
fix_k = self.args_dict.get("afterpulse_decay_factor_fixed_value")
|
|
226
|
+
|
|
227
|
+
x, y, y_err = self._read_afterpulse_spectrum_for_fit(
|
|
228
|
+
self.args_dict.get("afterpulse_spectrum"), ap_min
|
|
229
|
+
)
|
|
230
|
+
fit_func, p0, bounds = self.afterpulse_fit_function(fix_k=fix_k)
|
|
231
|
+
|
|
232
|
+
result = curve_fit(fit_func, x, y, sigma=y_err, p0=p0, bounds=bounds, absolute_sigma=True)
|
|
233
|
+
params, covariance = result[0], result[1]
|
|
234
|
+
param_errors = np.sqrt(np.diag(covariance))
|
|
235
|
+
predicted = fit_func(x, *params)
|
|
236
|
+
self._afterpulse_fit_statistics(x, y, y_err, params, param_errors, predicted, fix_k)
|
|
237
|
+
|
|
238
|
+
# table with fitted afterpulse spectrum
|
|
239
|
+
x_fit = np.arange(
|
|
240
|
+
ap_min, self.args_dict["afterpulse_amplitude_range"][1], self.args_dict["step_size"]
|
|
241
|
+
)
|
|
242
|
+
y_fit = fit_func(x_fit, *params)
|
|
243
|
+
return Table([x_fit, y_fit], names=["amplitude", self.afterpulse_column])
|
|
244
|
+
|
|
245
|
+
def afterpulse_fit_function(self, fix_k):
|
|
246
|
+
"""
|
|
247
|
+
Afterpulse fit function: exponential decay with linear term in the exponent.
|
|
248
|
+
|
|
249
|
+
Starting values and bounds are set for the other parameters using values typical
|
|
250
|
+
for LSTN-design. Allows to fix the K parameter.
|
|
251
|
+
|
|
252
|
+
Parameters
|
|
253
|
+
----------
|
|
254
|
+
fix_K : float
|
|
255
|
+
Fixed value for K parameter.
|
|
256
|
+
|
|
257
|
+
Returns
|
|
258
|
+
-------
|
|
259
|
+
function
|
|
260
|
+
Exponential decay function with linear term in the exponent.
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
def exp_decay(x, a, b, k):
|
|
264
|
+
return a * np.exp(-1.0 / (b * (k / (x + k))) * x)
|
|
265
|
+
|
|
266
|
+
p0 = [1e-5, 8.0] # Initial guess for [A, B] typical LSTN values
|
|
267
|
+
bounds_lower = [0, 0]
|
|
268
|
+
bounds_upper = [1.0, 20.0]
|
|
269
|
+
|
|
270
|
+
if fix_k is None:
|
|
271
|
+
p0.append(25.0)
|
|
272
|
+
bounds_lower.append(5.0)
|
|
273
|
+
bounds_upper.append(35.0)
|
|
274
|
+
return exp_decay, p0, (bounds_lower, bounds_upper)
|
|
275
|
+
|
|
276
|
+
def exp_decay_fixed_k(x, a, b):
|
|
277
|
+
return exp_decay(x, a, b, k=fix_k)
|
|
278
|
+
|
|
279
|
+
return exp_decay_fixed_k, p0, (bounds_lower, bounds_upper)
|
|
280
|
+
|
|
281
|
+
def _afterpulse_fit_statistics(self, x, y, y_err, params, param_errors, predicted, fix_k):
|
|
282
|
+
"""Print and return afterpulse fit statistics."""
|
|
283
|
+
chi2 = np.sum(((y - predicted) / y_err) ** 2)
|
|
284
|
+
ndf = len(x) - len(params)
|
|
285
|
+
|
|
286
|
+
result = {
|
|
287
|
+
"params": params.tolist(),
|
|
288
|
+
"errors": param_errors.tolist(),
|
|
289
|
+
"chi2_ndf": chi2 / ndf if ndf > 0 else np.nan,
|
|
290
|
+
}
|
|
291
|
+
if fix_k is not None:
|
|
292
|
+
result["params"].append(fix_k)
|
|
293
|
+
result["errors"].append(0.0)
|
|
294
|
+
|
|
295
|
+
self._logger.info(f"Fit results: {result}")
|
|
296
|
+
return result
|
|
297
|
+
|
|
298
|
+
def _read_afterpulse_spectrum_for_fit(self, afterpulse_spectrum, fit_min_pe):
|
|
299
|
+
"""
|
|
300
|
+
Read afterpulse spectrum data for fitting.
|
|
301
|
+
|
|
302
|
+
Parameters
|
|
303
|
+
----------
|
|
304
|
+
afterpulse_spectrum : str
|
|
305
|
+
Afterpulse spectrum data file.
|
|
306
|
+
fit_min_pe : float
|
|
307
|
+
Minimum amplitude for fitting.
|
|
308
|
+
|
|
309
|
+
Returns
|
|
310
|
+
-------
|
|
311
|
+
tuple
|
|
312
|
+
Tuple with x, y, y_err data for fitting.
|
|
313
|
+
"""
|
|
314
|
+
table = Table.read(afterpulse_spectrum, format="ascii.ecsv")
|
|
315
|
+
x = table["amplitude"]
|
|
316
|
+
y = table[self.afterpulse_column]
|
|
317
|
+
y_err = table["frequency stdev (afterpulsing)"]
|
|
318
|
+
mask = (x >= fit_min_pe) & (y > 0)
|
|
319
|
+
x_fit, y_fit, y_err_fit = x[mask], y[mask], y_err[mask]
|
|
320
|
+
return x_fit, y_fit, y_err_fit
|
|
@@ -269,6 +269,7 @@ class ModelDataWriter:
|
|
|
269
269
|
"unit": unit,
|
|
270
270
|
"type": self._get_parameter_type(),
|
|
271
271
|
"file": self._parameter_is_a_file(),
|
|
272
|
+
"meta_parameter": False,
|
|
272
273
|
}
|
|
273
274
|
return self.validate_and_transform(
|
|
274
275
|
product_data_dict=data_dict,
|
|
@@ -426,7 +427,7 @@ class ModelDataWriter:
|
|
|
426
427
|
"""
|
|
427
428
|
Prepare data dictionary for writing to json file.
|
|
428
429
|
|
|
429
|
-
Ensure sim_telarray style lists as strings.
|
|
430
|
+
Ensure sim_telarray style lists as strings 'type' and 'unit' entries.
|
|
430
431
|
Replace "None" with "null" for unit field.
|
|
431
432
|
|
|
432
433
|
Parameters
|
|
@@ -441,13 +442,13 @@ class ModelDataWriter:
|
|
|
441
442
|
|
|
442
443
|
"""
|
|
443
444
|
try:
|
|
444
|
-
data_dict["value"] = gen.convert_list_to_string(data_dict["value"])
|
|
445
|
-
data_dict["unit"] = gen.convert_list_to_string(data_dict["unit"], comma_separated=True)
|
|
446
|
-
data_dict["type"] = gen.convert_list_to_string(
|
|
447
|
-
data_dict["type"], comma_separated=True, collapse_list=True
|
|
448
|
-
)
|
|
449
445
|
if isinstance(data_dict["unit"], str):
|
|
450
446
|
data_dict["unit"] = data_dict["unit"].replace("None", "null")
|
|
447
|
+
elif isinstance(data_dict["unit"], list):
|
|
448
|
+
data_dict["unit"] = [
|
|
449
|
+
unit.replace("None", "null") if isinstance(unit, str) else unit
|
|
450
|
+
for unit in data_dict["unit"]
|
|
451
|
+
]
|
|
451
452
|
except KeyError:
|
|
452
453
|
pass
|
|
453
454
|
return data_dict
|
simtools/db/db_handler.py
CHANGED
|
@@ -15,7 +15,7 @@ from pymongo import MongoClient
|
|
|
15
15
|
from simtools.data_model import validate_data
|
|
16
16
|
from simtools.io_operations import io_handler
|
|
17
17
|
from simtools.simtel import simtel_table_reader
|
|
18
|
-
from simtools.utils import names, value_conversion
|
|
18
|
+
from simtools.utils import general, names, value_conversion
|
|
19
19
|
|
|
20
20
|
__all__ = ["DatabaseHandler"]
|
|
21
21
|
|
|
@@ -273,8 +273,6 @@ class DatabaseHandler:
|
|
|
273
273
|
"""
|
|
274
274
|
Get model parameters for all model versions.
|
|
275
275
|
|
|
276
|
-
Queries parameters for design and for the specified array element (if necessary).
|
|
277
|
-
|
|
278
276
|
Parameters
|
|
279
277
|
----------
|
|
280
278
|
site: str
|
|
@@ -290,10 +288,16 @@ class DatabaseHandler:
|
|
|
290
288
|
"""
|
|
291
289
|
pars = defaultdict(dict)
|
|
292
290
|
for _model_version in self.get_model_versions(collection):
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
291
|
+
try:
|
|
292
|
+
parameter_data = self.get_model_parameters(
|
|
293
|
+
site, array_element_name, collection, _model_version
|
|
294
|
+
)
|
|
295
|
+
pars[_model_version].update(parameter_data)
|
|
296
|
+
except KeyError:
|
|
297
|
+
self._logger.debug(
|
|
298
|
+
f"Skipping model version {_model_version} - {array_element_name} not found"
|
|
299
|
+
)
|
|
300
|
+
continue
|
|
297
301
|
return pars
|
|
298
302
|
|
|
299
303
|
def _get_parameter_for_model_version(
|
|
@@ -795,10 +799,12 @@ class DatabaseHandler:
|
|
|
795
799
|
f"corresponding to the {par_dict['parameter']} parameter, must be provided."
|
|
796
800
|
)
|
|
797
801
|
file_path = Path(file_prefix).joinpath(par_dict["value"])
|
|
802
|
+
if not general.is_utf8_file(file_path):
|
|
803
|
+
raise ValueError(f"File is not UTF-8 encoded: {file_path}")
|
|
798
804
|
files_to_add_to_db.add(f"{file_path}")
|
|
799
805
|
|
|
800
806
|
self._logger.info(
|
|
801
|
-
f"Adding a new entry to DB {db_name} and collection {
|
|
807
|
+
f"Adding a new entry to DB {db_name} and collection {collection_name}:\n{par_dict}"
|
|
802
808
|
)
|
|
803
809
|
collection.insert_one(par_dict)
|
|
804
810
|
|
simtools/dependencies.py
CHANGED
|
@@ -81,18 +81,53 @@ def get_sim_telarray_version():
|
|
|
81
81
|
|
|
82
82
|
def get_corsika_version():
|
|
83
83
|
"""
|
|
84
|
-
Get the version of the
|
|
84
|
+
Get the version of the CORSIKA package.
|
|
85
85
|
|
|
86
86
|
Returns
|
|
87
87
|
-------
|
|
88
88
|
str
|
|
89
|
-
Version of the
|
|
89
|
+
Version of the CORSIKA package.
|
|
90
90
|
"""
|
|
91
|
+
version = None
|
|
92
|
+
sim_telarray_path = os.getenv("SIMTOOLS_SIMTEL_PATH")
|
|
93
|
+
if sim_telarray_path is None:
|
|
94
|
+
_logger.warning("Environment variable SIMTOOLS_SIMTEL_PATH is not set.")
|
|
95
|
+
return None
|
|
96
|
+
corsika_command = Path(sim_telarray_path) / "corsika-run" / "corsika"
|
|
97
|
+
|
|
98
|
+
# Below I do not use the standard context manager because
|
|
99
|
+
# it makes mocking in the tests significantly more difficult
|
|
100
|
+
process = subprocess.Popen( # pylint: disable=consider-using-with
|
|
101
|
+
corsika_command,
|
|
102
|
+
stdout=subprocess.PIPE,
|
|
103
|
+
stderr=subprocess.PIPE,
|
|
104
|
+
stdin=subprocess.PIPE,
|
|
105
|
+
text=True,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Capture output until it waits for input
|
|
109
|
+
while True:
|
|
110
|
+
line = process.stdout.readline()
|
|
111
|
+
if not line:
|
|
112
|
+
break
|
|
113
|
+
# Extract the version from the line "NUMBER OF VERSION : 7.7550"
|
|
114
|
+
if "NUMBER OF VERSION" in line:
|
|
115
|
+
version = line.split(":")[1].strip()
|
|
116
|
+
break
|
|
117
|
+
# Check for a specific prompt or indication that the program is waiting for input
|
|
118
|
+
if "DATA CARDS FOR RUN STEERING ARE EXPECTED FROM STANDARD INPUT" in line:
|
|
119
|
+
break
|
|
120
|
+
|
|
121
|
+
process.terminate()
|
|
122
|
+
# Check it's a valid version string
|
|
123
|
+
if version and re.match(r"\d+\.\d+", version):
|
|
124
|
+
return version
|
|
91
125
|
try:
|
|
92
126
|
build_opts = get_build_options()
|
|
93
127
|
except (FileNotFoundError, TypeError):
|
|
94
|
-
_logger.warning("
|
|
128
|
+
_logger.warning("Could not get CORSIKA version.")
|
|
95
129
|
return None
|
|
130
|
+
_logger.debug("Getting the CORSIKA version from the build options.")
|
|
96
131
|
return build_opts.get("corsika_version")
|
|
97
132
|
|
|
98
133
|
|
simtools/layout/array_layout.py
CHANGED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""Retrieve, merge, and write layouts from CTAO common identifiers repository."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import simtools.utils.general as gen
|
|
7
|
+
from simtools.data_model.metadata_collector import MetadataCollector
|
|
8
|
+
from simtools.data_model.model_data_writer import ModelDataWriter
|
|
9
|
+
from simtools.io_operations import io_handler
|
|
10
|
+
from simtools.utils import names
|
|
11
|
+
|
|
12
|
+
_logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def retrieve_array_layouts(site, repository_url, branch_name="main"):
|
|
16
|
+
"""
|
|
17
|
+
Retrieve array layouts from CTAO common identifiers repository.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
site : str
|
|
22
|
+
Site identifier.
|
|
23
|
+
repository_url : str
|
|
24
|
+
URL or path to CTAO common identifiers
|
|
25
|
+
branch_name : str
|
|
26
|
+
Repository branch to use for CTAO common identifiers.
|
|
27
|
+
|
|
28
|
+
Returns
|
|
29
|
+
-------
|
|
30
|
+
dict
|
|
31
|
+
Array layouts for all CTAO sites.
|
|
32
|
+
"""
|
|
33
|
+
_logger.info(f"Retrieving array layouts from {repository_url} on branch {branch_name}.")
|
|
34
|
+
|
|
35
|
+
if gen.is_url(repository_url):
|
|
36
|
+
array_element_ids = gen.collect_data_from_http(
|
|
37
|
+
url=f"{repository_url}/{branch_name}/array-element-ids.json"
|
|
38
|
+
)
|
|
39
|
+
sub_arrays = gen.collect_data_from_http(
|
|
40
|
+
url=f"{repository_url}/{branch_name}/subarray-ids.json"
|
|
41
|
+
)
|
|
42
|
+
else:
|
|
43
|
+
array_element_ids = gen.collect_data_from_file(
|
|
44
|
+
Path(repository_url) / "array-element-ids.json"
|
|
45
|
+
)
|
|
46
|
+
sub_arrays = gen.collect_data_from_file(Path(repository_url) / "subarray-ids.json")
|
|
47
|
+
|
|
48
|
+
return _get_layouts_per_site(site, sub_arrays, array_element_ids)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _get_layouts_per_site(site, sub_arrays, array_element_ids):
|
|
52
|
+
"""
|
|
53
|
+
Get array layouts for CTAO sites.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
site : str
|
|
58
|
+
Site identifier.
|
|
59
|
+
sub_arrays : dict
|
|
60
|
+
Sub-array definitions.
|
|
61
|
+
array_element_ids : dict
|
|
62
|
+
Array element definitions.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
dict
|
|
67
|
+
Array layouts for CTAO sites.
|
|
68
|
+
"""
|
|
69
|
+
layouts_per_site = []
|
|
70
|
+
|
|
71
|
+
for array in sub_arrays.get("subarrays", []):
|
|
72
|
+
elements = []
|
|
73
|
+
for ids in array.get("array_element_ids", []):
|
|
74
|
+
element_name = _get_array_element_name(ids, array_element_ids)
|
|
75
|
+
if names.get_site_from_array_element_name(element_name) != site:
|
|
76
|
+
break
|
|
77
|
+
elements.append(element_name)
|
|
78
|
+
if len(elements) > 0:
|
|
79
|
+
array_layout = {
|
|
80
|
+
"name": array.get("name"),
|
|
81
|
+
"elements": elements,
|
|
82
|
+
}
|
|
83
|
+
layouts_per_site.append(array_layout)
|
|
84
|
+
|
|
85
|
+
_logger.info(f"CTAO array layout definition: {layouts_per_site}")
|
|
86
|
+
return layouts_per_site
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _get_array_element_name(ids, array_element_ids):
|
|
90
|
+
"""Return array element name for common identifier."""
|
|
91
|
+
for element in array_element_ids.get("array_elements", []):
|
|
92
|
+
if element.get("id") == ids:
|
|
93
|
+
return element.get("name")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def merge_array_layouts(layouts_1, layouts_2):
|
|
98
|
+
"""
|
|
99
|
+
Compare array layout dictionaries and merge them.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
layouts_1 : dict
|
|
104
|
+
Array layout dictionary 1.
|
|
105
|
+
layouts_2 : dict
|
|
106
|
+
Array layout dictionary 2.
|
|
107
|
+
|
|
108
|
+
Returns
|
|
109
|
+
-------
|
|
110
|
+
dict
|
|
111
|
+
Merged array layout dictionary based on layout_1.
|
|
112
|
+
"""
|
|
113
|
+
merged_layout = layouts_1
|
|
114
|
+
for layout_2 in layouts_2:
|
|
115
|
+
layout_found = False
|
|
116
|
+
for layout_1 in layouts_1.get("value", {}):
|
|
117
|
+
if sorted(layout_1["elements"]) == sorted(layout_2["elements"]):
|
|
118
|
+
print(
|
|
119
|
+
f"Equal telescope list: simtools '{layout_1['name']}' "
|
|
120
|
+
f"and CTAO '{layout_2['name']}'"
|
|
121
|
+
)
|
|
122
|
+
layout_1["name"] = layout_2["name"]
|
|
123
|
+
layout_found = True
|
|
124
|
+
if not layout_found:
|
|
125
|
+
merged_layout["value"].append(
|
|
126
|
+
{
|
|
127
|
+
"name": layout_2["name"],
|
|
128
|
+
"elements": layout_2["elements"],
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
_logger.info(f"Adding {layout_2['name']} with {layout_2['elements']}")
|
|
132
|
+
return merged_layout
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def write_array_layouts(array_layouts, args_dict, db_config):
|
|
136
|
+
"""
|
|
137
|
+
Write array layouts as model parameter.
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
args_dict : dict
|
|
142
|
+
Command line arguments.
|
|
143
|
+
array_layouts : dict
|
|
144
|
+
Array layouts to be written.
|
|
145
|
+
db_config : dict
|
|
146
|
+
Database configuration.
|
|
147
|
+
"""
|
|
148
|
+
_logger.info(f"Writing updated array layouts to the database for site {args_dict['site']}.")
|
|
149
|
+
|
|
150
|
+
io_handler_instance = io_handler.IOHandler()
|
|
151
|
+
io_handler_instance.set_paths(
|
|
152
|
+
output_path=args_dict["output_path"],
|
|
153
|
+
use_plain_output_path=args_dict["use_plain_output_path"],
|
|
154
|
+
)
|
|
155
|
+
output_file = io_handler_instance.get_output_file(
|
|
156
|
+
f"array-layouts-{args_dict['updated_parameter_version']}.json"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
ModelDataWriter.dump_model_parameter(
|
|
160
|
+
parameter_name="array_layouts",
|
|
161
|
+
value=array_layouts["value"],
|
|
162
|
+
instrument=args_dict["site"],
|
|
163
|
+
parameter_version=args_dict.get("updated_parameter_version"),
|
|
164
|
+
output_file=output_file,
|
|
165
|
+
use_plain_output_path=args_dict["use_plain_output_path"],
|
|
166
|
+
db_config=db_config,
|
|
167
|
+
)
|
|
168
|
+
MetadataCollector.dump(
|
|
169
|
+
args_dict,
|
|
170
|
+
output_file,
|
|
171
|
+
add_activity_name=True,
|
|
172
|
+
)
|
simtools/model/array_model.py
CHANGED
|
@@ -12,7 +12,7 @@ from simtools.io_operations import io_handler
|
|
|
12
12
|
from simtools.model.site_model import SiteModel
|
|
13
13
|
from simtools.model.telescope_model import TelescopeModel
|
|
14
14
|
from simtools.simtel.simtel_config_writer import SimtelConfigWriter
|
|
15
|
-
from simtools.utils import
|
|
15
|
+
from simtools.utils import names
|
|
16
16
|
|
|
17
17
|
__all__ = ["ArrayModel"]
|
|
18
18
|
|
|
@@ -326,12 +326,11 @@ class ArrayModel:
|
|
|
326
326
|
"site": site,
|
|
327
327
|
"parameter_version": parameter_version,
|
|
328
328
|
"unique_id": None,
|
|
329
|
-
"value":
|
|
330
|
-
[x.to("m").value, y.to("m").value, z.to("m").value]
|
|
331
|
-
),
|
|
329
|
+
"value": [x.to("m").value, y.to("m").value, z.to("m").value],
|
|
332
330
|
"unit": "m",
|
|
333
331
|
"type": "float64",
|
|
334
332
|
"file": False,
|
|
333
|
+
"meta_parameter": False,
|
|
335
334
|
}
|
|
336
335
|
|
|
337
336
|
def _get_array_elements_from_list(self, array_elements_list: list[str]) -> dict:
|