"""Test consistency of sim_telarray metadata."""
import logging
import numpy as np
from simtools.simtel.simtel_config_reader import SimtelConfigReader
from simtools.simtel.simtel_io_metadata import (
get_sim_telarray_telescope_id,
read_sim_telarray_metadata,
)
_logger = logging.getLogger(__name__)
def _assert_model_parameters(metadata, model):
"""
Assert that model parameter values matches the values in the sim_telarray metadata.
Parameters
----------
metadata: dict
Metadata dictionary.
model: SiteModel, TelescopeModel
Model to compare with.
Returns
-------
invalid_parameter_list: list
List of parameters that do not match.
"""
config_reader = SimtelConfigReader()
invalid_parameter_list = []
for param in model.parameters:
sim_telarray_name = _sim_telarray_name_from_parameter_name(param)
if sim_telarray_name in metadata.keys():
parameter_type = model.parameters[param]["type"]
if parameter_type not in ("string", "dict", "boolean"):
value, _ = config_reader.extract_value_from_sim_telarray_column(
[metadata[sim_telarray_name]], parameter_type
)
else:
value = metadata[sim_telarray_name]
value = (int)(value) if value.isnumeric() else value
_logger.debug(
f"Parameter {param} in sim_telarray file: {value}, "
f"in model: {model.parameters[param]['value']}"
)
if not is_equal(value, model.parameters[param]["value"], parameter_type):
invalid_parameter_list.append(
f"Parameter {param} mismatch between sim_telarray file: {value}, "
f"and model: {model.parameters[param]['value']}"
)
return invalid_parameter_list
def _sim_telarray_name_from_parameter_name(parameter_name):
"""Return sim_telarray parameter name. Some specific fine tuning."""
# parameters like "reference_point_latitude"
sim_telarray_name = parameter_name.replace("reference_point_", "")
if sim_telarray_name == "altitude":
return "corsika_observation_level"
if sim_telarray_name == "array_triggers":
return None
return sim_telarray_name
[docs]
def is_equal(value1, value2, value_type):
"""
Check if two values are equal based on their type.
The complexity of this function reflects the complexity of the sim_telarray
metadata output.
Parameters
----------
value1: any
First value to compare.
value2: any
Second value to compare.
value_type: str
Type of the values ('string', 'dict', etc.).
Returns
-------
bool
True if the values are equal, False otherwise.
"""
value1 = value1[0] if isinstance(value1, tuple) else value1
value2 = value2[0] if isinstance(value2, tuple) else value2
if value1 is None or value2 is None:
if value1 in ("none", None) and value2 in ("none", None):
return True
if value_type == "string":
return str(value1).strip() == str(value2).strip()
if value_type == "dict":
return value1 == value2
if value_type == "boolean":
return bool(value1) == bool(value2)
return _is_equal_floats_or_ints(value1, value2)
def _is_equal_floats_or_ints(value1, value2):
"""Check if floats and ints are equal."""
if isinstance(value1, np.ndarray | list) and isinstance(value2, np.ndarray | list):
return bool(np.allclose(np.array(value1), np.array(value2), rtol=1e-10))
if isinstance(value1, list) and isinstance(value2, float | int | np.integer | np.floating):
if all(x == value1[0] for x in value1):
return bool(np.isclose(float(value1[0]), float(value2), rtol=1e-10))
if isinstance(value2, list) and isinstance(value1, float | int | np.integer | np.floating):
if all(x == value2[0] for x in value2):
return bool(np.isclose(float(value1), float(value2[0]), rtol=1e-10))
return bool(np.isclose(float(value1), float(value2), rtol=1e-10))