gammasimtools 0.12.0__py3-none-any.whl → 0.13.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 (81) hide show
  1. {gammasimtools-0.12.0.dist-info → gammasimtools-0.13.0.dist-info}/METADATA +1 -1
  2. {gammasimtools-0.12.0.dist-info → gammasimtools-0.13.0.dist-info}/RECORD +64 -77
  3. {gammasimtools-0.12.0.dist-info → gammasimtools-0.13.0.dist-info}/WHEEL +1 -1
  4. {gammasimtools-0.12.0.dist-info → gammasimtools-0.13.0.dist-info}/entry_points.txt +2 -1
  5. simtools/_version.py +2 -2
  6. simtools/applications/convert_all_model_parameters_from_simtel.py +77 -88
  7. simtools/applications/convert_geo_coordinates_of_array_elements.py +1 -1
  8. simtools/applications/db_get_parameter_from_db.py +52 -22
  9. simtools/applications/derive_photon_electron_spectrum.py +1 -1
  10. simtools/applications/docs_produce_array_element_report.py +1 -10
  11. simtools/applications/docs_produce_model_parameter_reports.py +4 -17
  12. simtools/applications/plot_tabular_data.py +14 -2
  13. simtools/applications/{production_derive_limits.py → production_derive_corsika_limits.py} +20 -8
  14. simtools/applications/production_extract_mc_event_data.py +125 -0
  15. simtools/applications/run_application.py +9 -10
  16. simtools/applications/submit_data_from_external.py +1 -1
  17. simtools/applications/submit_model_parameter_from_external.py +2 -1
  18. simtools/camera/single_photon_electron_spectrum.py +6 -2
  19. simtools/constants.py +7 -0
  20. simtools/data_model/metadata_collector.py +159 -61
  21. simtools/data_model/model_data_writer.py +11 -55
  22. simtools/data_model/schema.py +2 -1
  23. simtools/data_model/validate_data.py +5 -3
  24. simtools/db/db_handler.py +115 -31
  25. simtools/model/model_parameter.py +0 -31
  26. simtools/production_configuration/derive_corsika_limits.py +260 -0
  27. simtools/production_configuration/extract_mc_event_data.py +253 -0
  28. simtools/ray_tracing/mirror_panel_psf.py +1 -1
  29. simtools/reporting/docs_read_parameters.py +164 -91
  30. simtools/schemas/metadata.metaschema.yml +7 -6
  31. simtools/schemas/model_parameter.metaschema.yml +0 -4
  32. simtools/schemas/model_parameter_and_data_schema.metaschema.yml +13 -5
  33. simtools/schemas/model_parameters/array_coordinates.schema.yml +1 -1
  34. simtools/schemas/model_parameters/array_layouts.schema.yml +3 -0
  35. simtools/schemas/model_parameters/asum_shaping.schema.yml +1 -1
  36. simtools/schemas/model_parameters/atmospheric_profile.schema.yml +1 -1
  37. simtools/schemas/model_parameters/camera_config_file.schema.yml +1 -1
  38. simtools/schemas/model_parameters/camera_degraded_map.schema.yml +1 -1
  39. simtools/schemas/model_parameters/camera_filter.schema.yml +1 -1
  40. simtools/schemas/model_parameters/dsum_shaping.schema.yml +1 -1
  41. simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +1 -1
  42. simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +1 -1
  43. simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +3 -3
  44. simtools/schemas/model_parameters/fadc_max_sum.schema.yml +3 -3
  45. simtools/schemas/model_parameters/fake_mirror_list.schema.yml +1 -1
  46. simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +1 -1
  47. simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +1 -1
  48. simtools/schemas/model_parameters/mirror_list.schema.yml +1 -1
  49. simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +1 -1
  50. simtools/schemas/model_parameters/nsb_skymap.schema.yml +1 -1
  51. simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +1 -1
  52. simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +1 -1
  53. simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +1 -1
  54. simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +1 -1
  55. simtools/schemas/plot_configuration.metaschema.yml +162 -0
  56. simtools/schemas/production_tables.schema.yml +1 -1
  57. simtools/simtel/simtel_config_reader.py +85 -34
  58. simtools/simtel/simtel_table_reader.py +4 -0
  59. simtools/utils/general.py +50 -9
  60. simtools/utils/names.py +7 -2
  61. simtools/visualization/plot_tables.py +25 -20
  62. simtools/visualization/visualize.py +71 -23
  63. simtools/_dev_version/__init__.py +0 -9
  64. simtools/applications/__init__.py +0 -0
  65. simtools/configuration/__init__.py +0 -0
  66. simtools/corsika/__init__.py +0 -0
  67. simtools/data_model/__init__.py +0 -0
  68. simtools/db/__init__.py +0 -0
  69. simtools/io_operations/__init__.py +0 -0
  70. simtools/job_execution/__init__.py +0 -0
  71. simtools/layout/__init__.py +0 -0
  72. simtools/model/__init__.py +0 -0
  73. simtools/production_configuration/limits_calculation.py +0 -202
  74. simtools/ray_tracing/__init__.py +0 -0
  75. simtools/runners/__init__.py +0 -0
  76. simtools/simtel/__init__.py +0 -0
  77. simtools/testing/__init__.py +0 -0
  78. simtools/utils/__init__.py +0 -0
  79. simtools/visualization/__init__.py +0 -0
  80. {gammasimtools-0.12.0.dist-info → gammasimtools-0.13.0.dist-info}/LICENSE +0 -0
  81. {gammasimtools-0.12.0.dist-info → gammasimtools-0.13.0.dist-info}/top_level.txt +0 -0
@@ -115,6 +115,7 @@ definitions:
115
115
  - number
116
116
  - string
117
117
  - boolean
118
+ - "null"
118
119
  table_columns:
119
120
  type: array
120
121
  items:
@@ -265,12 +266,15 @@ definitions:
265
266
  - class
266
267
  title: Instrument
267
268
  InstrumentTypeElement:
268
- type: string
269
+ type:
270
+ - string
271
+ - "null"
269
272
  description: "specific type of instrument"
270
273
  enum:
271
274
  - Atmosphere
272
275
  - Observatory
273
276
  - None
277
+ - null
274
278
  title: InstrumentTypeElement
275
279
  SimulationSoftware:
276
280
  type: object
@@ -297,7 +301,9 @@ definitions:
297
301
  - $ref: '#/definitions/DataClass'
298
302
  title: DataUnion
299
303
  Setting:
300
- type: string
304
+ type:
305
+ - string
306
+ - "null"
301
307
  description: "list of setting workflows"
302
308
  enum:
303
309
  - SetArrayElementCoordinates
@@ -315,10 +321,12 @@ definitions:
315
321
  - SetTelescopeFiducialSphere
316
322
  - SetTelescopeShadowingParameters
317
323
  - SetTriggerThresholdsFromRateScan
318
- - None
324
+ - null
319
325
  title: Setting
320
326
  Validation:
321
- type: string
327
+ type:
328
+ - string
329
+ - "null"
322
330
  description: "list of validation workflows"
323
331
  enum:
324
332
  - ValidateArrayElementCoordinates
@@ -344,7 +352,7 @@ definitions:
344
352
  - ValidateTelescopeStructure
345
353
  - ValidateTriggerPerformance
346
354
  - ValidationWorkflowMissing
347
- - None
355
+ - null
348
356
  TableColumnType:
349
357
  type: string
350
358
  enum:
@@ -12,7 +12,7 @@ description: |-
12
12
  data:
13
13
  - type: file
14
14
  unit: dimensionless
15
- default: None
15
+ default: null
16
16
  instrument:
17
17
  class: Site
18
18
  type:
@@ -24,6 +24,9 @@ data:
24
24
  type: string
25
25
  format: array_element
26
26
  description: Name of the array element.
27
+ comment:
28
+ type: string
29
+ description: Additional comment.
27
30
  required:
28
31
  - name
29
32
  - elements
@@ -13,7 +13,7 @@ description: |-
13
13
  data:
14
14
  - type: file
15
15
  unit: dimensionless
16
- default: None
16
+ default: null
17
17
  instrument:
18
18
  class: Camera
19
19
  type:
@@ -11,7 +11,7 @@ description: Density, thickness, and index of refraction as function of altitude
11
11
  data:
12
12
  - type: file
13
13
  unit: dimensionless
14
- default: None
14
+ default: null
15
15
  instrument:
16
16
  class: Site
17
17
  type:
@@ -15,7 +15,7 @@ description: |-
15
15
  data:
16
16
  - type: file
17
17
  unit: dimensionless
18
- default: None
18
+ default: null
19
19
  instrument:
20
20
  class: Camera
21
21
  type:
@@ -19,7 +19,7 @@ short_description: |-
19
19
  data:
20
20
  - type: file
21
21
  unit: dimensionless
22
- default: None
22
+ default: null
23
23
  instrument:
24
24
  class: Camera
25
25
  type:
@@ -22,7 +22,7 @@ short_description: |-
22
22
  data:
23
23
  - type: file
24
24
  unit: dimensionless
25
- default: None
25
+ default: null
26
26
  instrument:
27
27
  class: Camera
28
28
  type:
@@ -24,7 +24,7 @@ short_description: |-
24
24
  data:
25
25
  - type: file
26
26
  unit: dimensionless
27
- default: None
27
+ default: null
28
28
  instrument:
29
29
  class: Camera
30
30
  type:
@@ -25,7 +25,7 @@ data:
25
25
  instrument:
26
26
  class: Camera
27
27
  type:
28
- - None
28
+ - null
29
29
  activity:
30
30
  setting:
31
31
  - SetParameterFromExternal
@@ -24,7 +24,7 @@ data:
24
24
  instrument:
25
25
  class: Camera
26
26
  type:
27
- - None
27
+ - null
28
28
  activity:
29
29
  setting:
30
30
  - SetParameterFromExternal
@@ -27,12 +27,12 @@ data:
27
27
  instrument:
28
28
  class: Camera
29
29
  type:
30
- - None
30
+ - null
31
31
  activity:
32
32
  setting:
33
- - None
33
+ - null
34
34
  validation:
35
- - None
35
+ - null
36
36
  source:
37
37
  - Initial instrument setup
38
38
  simulation_software:
@@ -27,12 +27,12 @@ data:
27
27
  instrument:
28
28
  class: Camera
29
29
  type:
30
- - None
30
+ - null
31
31
  activity:
32
32
  setting:
33
- - None
33
+ - null
34
34
  validation:
35
- - None
35
+ - null
36
36
  source:
37
37
  - Initial instrument setup
38
38
  simulation_software:
@@ -15,7 +15,7 @@ description: |-
15
15
  data:
16
16
  - type: file
17
17
  unit: dimensionless
18
- default: None
18
+ default: null
19
19
  instrument:
20
20
  class: Structure
21
21
  type:
@@ -17,7 +17,7 @@ short_description: Lightguide efficiency as a function of incidence angle.
17
17
  data:
18
18
  - type: file
19
19
  unit: dimensionless
20
- default: None
20
+ default: null
21
21
  instrument:
22
22
  class: Camera
23
23
  type:
@@ -19,7 +19,7 @@ description: Lightguide efficiency for on-axis photons vs wavelength.
19
19
  data:
20
20
  - type: file
21
21
  unit: dimensionless
22
- default: None
22
+ default: null
23
23
  instrument:
24
24
  class: Camera
25
25
  type:
@@ -11,7 +11,7 @@ description: List of mirror positions, diameters, focal lengths, and shape codes
11
11
  data:
12
12
  - type: file
13
13
  unit: dimensionless
14
- default: None
14
+ default: null
15
15
  instrument:
16
16
  class: Structure
17
17
  type:
@@ -15,7 +15,7 @@ description: |-
15
15
  data:
16
16
  - type: file
17
17
  unit: dimensionless
18
- default: None
18
+ default: null
19
19
  instrument:
20
20
  class: Site
21
21
  type:
@@ -20,7 +20,7 @@ short_description: Sky map (Az/Alt) of NSB enhancement factors.
20
20
  data:
21
21
  - type: file
22
22
  unit: dimensionless
23
- default: None
23
+ default: null
24
24
  instrument:
25
25
  class: Site
26
26
  type:
@@ -22,7 +22,7 @@ short_description: |-
22
22
  data:
23
23
  - type: file
24
24
  unit: dimensionless
25
- default: None
25
+ default: null
26
26
  instrument:
27
27
  class: Structure
28
28
  type:
@@ -14,7 +14,7 @@ short_description: |-
14
14
  data:
15
15
  - type: file
16
16
  unit: dimensionless
17
- default: None
17
+ default: null
18
18
  instrument:
19
19
  class: Structure
20
20
  type:
@@ -22,7 +22,7 @@ short_description: |-
22
22
  data:
23
23
  - type: file
24
24
  unit: dimensionless
25
- default: None
25
+ default: null
26
26
  instrument:
27
27
  class: Structure
28
28
  type:
@@ -17,7 +17,7 @@ short_description: |-
17
17
  data:
18
18
  - type: file
19
19
  unit: dimensionless
20
- default: None
20
+ default: null
21
21
  instrument:
22
22
  class: Structure
23
23
  type:
@@ -0,0 +1,162 @@
1
+ ---
2
+ $schema: http://json-schema.org/draft-06/schema#
3
+ $ref: '#/definitions/SimtoolsPlotConfiguration'
4
+ title: SimPipe plot configuration metaschema
5
+ description: YAML representation of plot configuration metaschema
6
+ version: 0.1.0
7
+ name: plot_configuration.metaschema
8
+ type: object
9
+ additionalProperties: false
10
+
11
+ definitions:
12
+ SimtoolsPlotConfiguration:
13
+ type: object
14
+ additionalProperties: false
15
+ properties:
16
+ CTA_SIMPIPE:
17
+ "$ref": "#/definitions/CTASIMPIPE"
18
+ SCHEMA_VERSION:
19
+ type: string
20
+ description: "Version of the schema."
21
+ SCHEMA_URL:
22
+ type: string
23
+ format: uri
24
+ description: "URL of the schema."
25
+ SCHEMA_NAME:
26
+ type: string
27
+ description: "Name of the schema."
28
+ required:
29
+ - CTA_SIMPIPE
30
+ title: "SimtoolsPlotConfiguration"
31
+ CTASIMPIPE:
32
+ type: object
33
+ additionalProperties: false
34
+ properties:
35
+ PLOT:
36
+ "$ref": "#/definitions/Plot"
37
+ required:
38
+ - PLOT
39
+ title: "CTASimpipe"
40
+ Plot:
41
+ description: "Plot configuration of simtools data visualization."
42
+ type: object
43
+ additionalProperties: false
44
+ properties:
45
+ TYPE:
46
+ type: string
47
+ description: "Type of the plot (e.g., mirror reflectivity, quantum_efficiency)."
48
+ TITLE:
49
+ type: string
50
+ description: "Title of the plot."
51
+ XTITLE:
52
+ type: string
53
+ description: "Title of x-axis."
54
+ YTITLE:
55
+ type: string
56
+ description: "Title of y-axis."
57
+ XSCALE:
58
+ type: string
59
+ enum: ["linear", "log"]
60
+ description: "Scale of x-axis (linear or log)."
61
+ YSCALE:
62
+ type: string
63
+ enum: ["linear", "log"]
64
+ description: "Scale of y-axis (linear or log)."
65
+ XLIM:
66
+ type: array
67
+ items:
68
+ type: [number, "null"]
69
+ description: "Limits for x-axis [min, max]. Use null for auto-limit."
70
+ minItems: 2
71
+ maxItems: 2
72
+ YLIM:
73
+ type: array
74
+ items:
75
+ type: [number, "null"]
76
+ description: "Limits for y-axis [min, max]. Use null for auto-limit."
77
+ minItems: 2
78
+ maxItems: 2
79
+ ERROR_TYPE:
80
+ type: string
81
+ enum: ["fill_between", "errorbar", "none"]
82
+ description: "Type of errors."
83
+ NO_MARKERS:
84
+ type: boolean
85
+ description: "Whether to display markers on data points."
86
+ PLOT_RATIO:
87
+ type: boolean
88
+ description: "Whether to display ratio plot."
89
+ TABLES:
90
+ type: array
91
+ description: "List of tables to plot."
92
+ items:
93
+ "$ref": "#/definitions/TableConfig"
94
+ required:
95
+ - TYPE
96
+ - TITLE
97
+ - XTITLE
98
+ - YTITLE
99
+ - TABLES
100
+ title: "Plot"
101
+ TableConfig:
102
+ type: object
103
+ description: "Configuration for a data table to plot."
104
+ additionalProperties: false
105
+ properties:
106
+ PARAMETER:
107
+ type: string
108
+ description: "Parameter name to retrieve data for."
109
+ FILE_NAME:
110
+ type: string
111
+ description: "Path to the data file."
112
+ TYPE:
113
+ type: string
114
+ description: "Type of data file."
115
+ TELESCOPE:
116
+ type: string
117
+ description: "Telescope descriptor to retrieve data for."
118
+ SITE:
119
+ type: string
120
+ description: "Site name (North/South)."
121
+ MODEL_VERSION:
122
+ type: string
123
+ description: "Model version to use."
124
+ PARAMETER_VERSION:
125
+ type: string
126
+ description: "Parameter version to use."
127
+ LABEL:
128
+ type: string
129
+ description: "Label for the plot legend."
130
+ COLUMN_X:
131
+ type: string
132
+ description: "Column name to use for x-axis."
133
+ COLUMN_Y:
134
+ type: string
135
+ description: "Column name to use for y-axis."
136
+ COLUMN_X_ERR:
137
+ type: string
138
+ description: "Column name to use for x-axis error."
139
+ COLUMN_Y_ERR:
140
+ type: string
141
+ description: "Column name to use for y-axis error."
142
+ NORMALIZE_Y:
143
+ type: boolean
144
+ description: "Whether to normalize y values."
145
+ SELECT_VALUES:
146
+ type: object
147
+ description: "Selection criteria for data filtering."
148
+ properties:
149
+ COLUMN_NAME:
150
+ type: string
151
+ description: "Column name to use for filtering."
152
+ VALUE:
153
+ type: [number, string]
154
+ description: "Value to filter by."
155
+ required:
156
+ - COLUMN_NAME
157
+ - VALUE
158
+ required:
159
+ - COLUMN_X
160
+ - COLUMN_Y
161
+ - LABEL
162
+ title: "TableConfig"
@@ -29,7 +29,7 @@ definitions:
29
29
  pattern: '^\d+\.\d+\.\d+$'
30
30
  propertyNames:
31
31
  description: Allowed parameter name patterns.
32
- pattern: '^([A-Za-z](ST|LL)[N,S,x]-\d{2,3}|[A-Za-z](ST|LL)[N,S,x]-(design|FlashCam|NectarCam)|OBS-(North|South)|Dummy-Telescope)$'
32
+ pattern: '^([A-Za-z](ST|LL|CT)[N,S,x]-\d{2,3}|[A-Za-z](ST|LL|CT)[N,S,x]-(design|FlashCam|NectarCam)|OBS-(North|South)|Dummy-Telescope)$'
33
33
  design_model:
34
34
  type: object
35
35
  description: Design models.
@@ -4,13 +4,38 @@
4
4
  import logging
5
5
  import re
6
6
 
7
+ import astropy.units as u
7
8
  import numpy as np
8
9
 
9
10
  import simtools.utils.general as gen
11
+ from simtools.utils import names
10
12
 
11
13
  __all__ = ["SimtelConfigReader"]
12
14
 
13
15
 
16
+ def get_list_of_simtel_parameters(simtel_config_file):
17
+ """
18
+ Return list of simtel parameters found in simtel configuration file.
19
+
20
+ Parameters
21
+ ----------
22
+ simtel_config_file: str
23
+ File name for sim_telarray configuration
24
+
25
+ Returns
26
+ -------
27
+ list
28
+ List of parameters found in simtel configuration file.
29
+
30
+ """
31
+ simtel_parameter_set = set()
32
+ with open(simtel_config_file, encoding="utf-8") as file:
33
+ for line in file:
34
+ parts_of_lines = re.split(r",\s*|\s+", line.strip())
35
+ simtel_parameter_set.add(parts_of_lines[1].lower())
36
+ return sorted(simtel_parameter_set)
37
+
38
+
14
39
  class SimtelConfigReader:
15
40
  """
16
41
  Reads model parameters from configuration files and converts to the simtools representation.
@@ -26,7 +51,7 @@ class SimtelConfigReader:
26
51
  -C limits=no-internal -C initlist=no-internal -C list=no-internal\
27
52
  -C typelist=no-internal -C maximum_telescopes=30\
28
53
  -DNSB_AUTOSCALE -DNECTARCAM -DHYPER_LAYOUT\
29
- -DNUM_TELESCOPES=30 /dev/null 2>|/dev/null | grep '(@cfg)'
54
+ -DNUM_TELESCOPES=30 /dev/null 2>|/dev/null | grep '(@cfg)' | sed 's/^(@cfg)
30
55
 
31
56
  Parameters
32
57
  ----------
@@ -61,7 +86,12 @@ class SimtelConfigReader:
61
86
  else None
62
87
  )
63
88
  self.parameter_name = self.schema_dict.get("name") if self.schema_dict else parameter_name
64
- self.simtel_parameter_name = self._get_simtel_parameter_name(self.parameter_name)
89
+ try:
90
+ self.simtel_parameter_name = names.get_simulation_software_name_from_parameter_name(
91
+ self.parameter_name
92
+ ).upper()
93
+ except (KeyError, AttributeError):
94
+ self.simtel_parameter_name = self.parameter_name.upper()
65
95
  self.simtel_telescope_name = simtel_telescope_name
66
96
  self.camera_pixels = camera_pixels
67
97
  self.parameter_dict = self.read_simtel_config_file(
@@ -73,7 +103,7 @@ class SimtelConfigReader:
73
103
  return data_type == "limits" and self.parameter_dict.get("type") == "bool"
74
104
 
75
105
  def _get_schema_values(self, data_type):
76
- """Check schema values for limits and defaults."""
106
+ """Check schema values for limits, unit, and default."""
77
107
  try:
78
108
  if data_type == "limits":
79
109
  _from_schema = [
@@ -82,14 +112,25 @@ class SimtelConfigReader:
82
112
  ]
83
113
  return _from_schema[0] if _from_schema[1] is None else _from_schema
84
114
  if len(self.schema_dict["data"]) == 1:
85
- return self.schema_dict["data"][0]["default"]
86
- return [data.get("default") for data in self.schema_dict["data"]]
115
+ return self.schema_dict["data"][0].get(data_type)
116
+ return [data.get(data_type) for data in self.schema_dict["data"]]
87
117
  except (KeyError, IndexError):
88
118
  return None
89
119
 
90
120
  @staticmethod
91
121
  def _values_match(_from_simtel, _from_schema):
92
- """Check if values match (are close for floats)."""
122
+ """
123
+ Check if values match (are close for floats).
124
+
125
+ Convert where necessary astropy.Quantity to float.
126
+
127
+ """
128
+ if isinstance(_from_simtel, u.Quantity):
129
+ _from_simtel = _from_simtel.value
130
+ if isinstance(_from_simtel, np.ndarray) and len(_from_simtel) > 0:
131
+ _from_simtel = np.array(
132
+ [v.value if isinstance(v, u.Quantity) else v for v in _from_simtel]
133
+ )
93
134
  try:
94
135
  if not isinstance(_from_schema, list | np.ndarray) and _from_simtel == _from_schema:
95
136
  return True
@@ -184,6 +225,7 @@ class SimtelConfigReader:
184
225
  dtype=_para_dict.get("type"),
185
226
  n_dim=_para_dict.get("dimension"),
186
227
  default=_para_dict.get("default"),
228
+ is_limit=(key == "limits"),
187
229
  )
188
230
  except KeyError:
189
231
  pass
@@ -232,7 +274,7 @@ class SimtelConfigReader:
232
274
 
233
275
  return column, except_from_all
234
276
 
235
- def _add_value_from_simtel_cfg(self, column, dtype=None, n_dim=1, default=None):
277
+ def _add_value_from_simtel_cfg(self, column, dtype=None, n_dim=1, default=None, is_limit=False):
236
278
  """
237
279
  Extract value(s) from simtel configuration file columns.
238
280
 
@@ -276,7 +318,42 @@ class SimtelConfigReader:
276
318
  if dtype == "bool":
277
319
  column = np.array([bool(int(item)) for item in column])
278
320
 
279
- return self._process_column(column, dtype)
321
+ column, ndim = self._process_column(column, dtype)
322
+ if not is_limit:
323
+ column = self._add_units(column)
324
+ return column, ndim
325
+
326
+ def _add_units(self, column):
327
+ """
328
+ Add units as given in schema file to column.
329
+
330
+ Take into account array types and dimensionless units.
331
+ Ensure that integer values are returned as integers (astropy converts
332
+ values to floats when multiplying them with units).
333
+
334
+ """
335
+ try:
336
+ unit = self._get_schema_values("unit")
337
+ except TypeError: # no schema defined
338
+ return column
339
+ if unit is None or unit == "dimensionless":
340
+ return column
341
+
342
+ if isinstance(column, np.ndarray) and len(column) == len(unit):
343
+ return np.array(
344
+ [
345
+ col * u.Unit(un) if un != "dimensionless" else col
346
+ for col, un in zip(column, unit)
347
+ ],
348
+ dtype=object,
349
+ )
350
+ if isinstance(unit, str):
351
+ column_with_unit = column * u.Unit(unit)
352
+ if isinstance(column, int | np.integer):
353
+ return u.Quantity(int(column_with_unit.value), unit, dtype=type(column))
354
+ return column_with_unit
355
+
356
+ return None
280
357
 
281
358
  def _process_column(self, column, dtype):
282
359
  """
@@ -324,29 +401,3 @@ class SimtelConfigReader:
324
401
  if self.camera_pixels is not None and self.simtel_parameter_name in ["NIGHTSKY_BACKGROUND"]:
325
402
  return str(np.dtype(column[0].lower())), self.camera_pixels
326
403
  return str(np.dtype(column[0].lower())), int(column[1])
327
-
328
- def _get_simtel_parameter_name(self, parameter_name):
329
- """
330
- Return parameter name as used in sim_telarray.
331
-
332
- This is documented in the schema file.
333
-
334
- Parameters
335
- ----------
336
- parameter_name: str
337
- Model parameter name (as used in simtools)
338
-
339
- Returns
340
- -------
341
- str
342
- Parameter name as used in sim_telarray.
343
-
344
- """
345
- try:
346
- for sim_soft in self.schema_dict["simulation_software"]:
347
- if sim_soft["name"] == "sim_telarray":
348
- return sim_soft["internal_parameter_name"].upper()
349
- except (KeyError, TypeError):
350
- pass
351
-
352
- return parameter_name.upper()
@@ -3,6 +3,7 @@
3
3
 
4
4
  import logging
5
5
  import re
6
+ from pathlib import Path
6
7
 
7
8
  import astropy.units as u
8
9
  from astropy.table import Table
@@ -253,6 +254,9 @@ def read_simtel_table(parameter_name, file_path):
253
254
  Table
254
255
  Astropy table.
255
256
  """
257
+ if Path(file_path).suffix == ".ecsv": # table is already in correct format
258
+ return Table.read(file_path, format="ascii.ecsv")
259
+
256
260
  if parameter_name == "atmospheric_transmission":
257
261
  return _read_simtel_data_for_atmospheric_transmission(file_path)
258
262