From d77d8c61431644fdef200299b055821f999dc53c Mon Sep 17 00:00:00 2001 From: Gernot Maier Date: Fri, 30 Jan 2026 14:16:24 +0100 Subject: [PATCH 1/3] Improve model parameter overwrite function --- docs/changes/2003.maintenance.md | 1 + src/simtools/model/model_parameter.py | 20 +++++++++++++------ .../ray_tracing/psf_parameter_optimisation.py | 2 +- src/simtools/visualization/plot_psf.py | 2 +- .../info_test_model_parameter_changes.yml | 10 +++++----- .../unit_tests/model/test_model_parameter.py | 6 +++--- .../test_psf_parameter_optimisation.py | 2 +- .../unit_tests/visualization/test_plot_psf.py | 4 +++- 8 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 docs/changes/2003.maintenance.md diff --git a/docs/changes/2003.maintenance.md b/docs/changes/2003.maintenance.md new file mode 100644 index 0000000000..fb6e9a4733 --- /dev/null +++ b/docs/changes/2003.maintenance.md @@ -0,0 +1 @@ +Improve model parameter overwrite function with an explicit `flat_dict` statement to avoid being flooded by warnings like `WARNING::model_parameter(l519)::overwrite_parameters::Parameter MSTS-05 not found in model MSTS-12, cannot overwrite it.` (note the error in the warning). diff --git a/src/simtools/model/model_parameter.py b/src/simtools/model/model_parameter.py index 998ec874ff..f69b589671 100644 --- a/src/simtools/model/model_parameter.py +++ b/src/simtools/model/model_parameter.py @@ -489,7 +489,7 @@ def _get_key_for_parameter_changes(self, site, array_element_name, changes_data) return None - def overwrite_parameters(self, changes): + def overwrite_parameters(self, changes, flat_dict=False): """ Change the value of multiple existing parameters in the model. @@ -497,9 +497,9 @@ def overwrite_parameters(self, changes): Allows for two types of 'changes' dictionary: - - simple: '{parameter_name: new_value, ...}' - - model repository style: - '{parameter_name: {"value": new_value, "version": new_version}, ...}' + - simple (flat_dict=True): '{parameter_name: new_value, ...}' + - model repository style (flat_dict=False): + '{array_element: {parameter_name: {"value": new_value, "version": new_version}, ...}}' Parameters ---------- @@ -508,11 +508,19 @@ def overwrite_parameters(self, changes): """ if not changes: return - key_for_changes = self._get_key_for_parameter_changes(self.site, self.name, changes) - changes = changes.get(key_for_changes, {}) if key_for_changes else changes + if not flat_dict: + key_for_changes = self._get_key_for_parameter_changes(self.site, self.name, changes) + changes = changes.get(key_for_changes, {}) if not changes: return + if flat_dict: + self._logger.warning(f"Overwriting parameters with changes: {changes}") + else: + self._logger.warning( + f"Overwriting parameters for {key_for_changes} with changes: {changes}" + ) + for par_name, par_value in changes.items(): if par_name not in self.parameters: self._logger.warning( diff --git a/src/simtools/ray_tracing/psf_parameter_optimisation.py b/src/simtools/ray_tracing/psf_parameter_optimisation.py index 71e9bc83bc..8a4dab4152 100644 --- a/src/simtools/ray_tracing/psf_parameter_optimisation.py +++ b/src/simtools/ray_tracing/psf_parameter_optimisation.py @@ -857,7 +857,7 @@ def _run_ray_tracing_simulation(tel_model, site_model, args_dict, pars): if pars is None: raise ValueError("No best parameters found") - tel_model.overwrite_parameters(pars) + tel_model.overwrite_parameters(pars, flat_dict=True) ray = RayTracing( telescope_model=tel_model, site_model=site_model, diff --git a/src/simtools/visualization/plot_psf.py b/src/simtools/visualization/plot_psf.py index b522a555f2..d2e70720fc 100644 --- a/src/simtools/visualization/plot_psf.py +++ b/src/simtools/visualization/plot_psf.py @@ -640,7 +640,7 @@ def create_psf_vs_offaxis_plot(tel_model, site_model, args_dict, best_pars, outp logger.info(f"Creating {psf_label_cm} vs off-axis angle plot with best parameters...") # Apply best parameters to telescope model - tel_model.overwrite_parameters(best_pars) + tel_model.overwrite_parameters(best_pars, flat_dict=True) # Create off-axis angle array max_offset = args_dict.get("max_offset", MAX_OFFSET_DEFAULT) diff --git a/tests/resources/info_test_model_parameter_changes.yml b/tests/resources/info_test_model_parameter_changes.yml index 8e01192d53..e113120328 100644 --- a/tests/resources/info_test_model_parameter_changes.yml +++ b/tests/resources/info_test_model_parameter_changes.yml @@ -16,23 +16,23 @@ changes: LSTS-01: effective_focal_length: version: '3.0.0' - value: '2923.7 0 0 2 0' + value: [2923.7, 0., 0., 2, 0.] # unchanged parameter for other LSTSs (test that no changes are applied) LSTS-design: effective_focal_length: version: '3.0.0' - value: '2923.7 0 0 0 0' + value: [2923.7, 0., 0., 0., 0.] # no changes expected for MSTs MSTS-05: effective_focal_length: version: '3.0.0' - value: '1644.51 0 0 0 0' + value: [1644.51, 0., 0., 0., 0.] # change parameters for all SSTSs except SSTS-22 SSTS-design: effective_focal_length: version: '3.0.0' - value: '315.191 0 0 0 0' + value: [315.191, 0., 0., 0., 0.] SSTS-22: effective_focal_length: version: '3.0.0' - value: '215.191 0 0 0 0' + value: [215.191, 0., 0., 0., 0.] diff --git a/tests/unit_tests/model/test_model_parameter.py b/tests/unit_tests/model/test_model_parameter.py index cfd8e16a9b..3b02108c33 100644 --- a/tests/unit_tests/model/test_model_parameter.py +++ b/tests/unit_tests/model/test_model_parameter.py @@ -213,7 +213,7 @@ def test_overwrite_parameters(telescope_model_lst, mocker): telescope_copy = copy.deepcopy(telescope_model_lst) mock_change = mocker.patch.object(TelescopeModel, "overwrite_model_parameter") telescope_copy.overwrite_parameters( - {"camera_pixels": {"value": 9999}, "mirror_focal_length": {"value": 55}} + {"camera_pixels": {"value": 9999}, "mirror_focal_length": {"value": 55}}, flat_dict=True ) mock_change.assert_any_call("camera_pixels", 9999, None) mock_change.assert_any_call("mirror_focal_length", 55, None) @@ -507,7 +507,7 @@ def test_overwrite_parameters_with_version_dict(telescope_model_lst): changes = {"num_gains": {"value": 4, "version": "2.0.0"}} - tel_model.overwrite_parameters(changes) + tel_model.overwrite_parameters(changes, flat_dict=True) assert tel_model.parameters["num_gains"]["value"] == 4 assert tel_model.parameters["num_gains"]["parameter_version"] == "2.0.0" @@ -520,7 +520,7 @@ def test_overwrite_parameters_with_simple_value(telescope_model_lst): # Simple value (not a dict with 'value' or 'version' keys) changes = {"num_gains": 5} - tel_model.overwrite_parameters(changes) + tel_model.overwrite_parameters(changes, flat_dict=True) assert tel_model.parameters["num_gains"]["value"] == 5 diff --git a/tests/unit_tests/ray_tracing/test_psf_parameter_optimisation.py b/tests/unit_tests/ray_tracing/test_psf_parameter_optimisation.py index dabf0f5473..c6cc96235f 100644 --- a/tests/unit_tests/ray_tracing/test_psf_parameter_optimisation.py +++ b/tests/unit_tests/ray_tracing/test_psf_parameter_optimisation.py @@ -253,7 +253,7 @@ def test__run_ray_tracing_simulation( mock_telescope_model, mock_site_model, mock_args_dict, pars ) assert psf_diameter == pytest.approx(expected_psf_diameter) - mock_telescope_model.overwrite_parameters.assert_called_once_with(pars) + mock_telescope_model.overwrite_parameters.assert_called_once_with(pars, flat_dict=True) @pytest.mark.parametrize( diff --git a/tests/unit_tests/visualization/test_plot_psf.py b/tests/unit_tests/visualization/test_plot_psf.py index 1331b1016e..2f94264710 100644 --- a/tests/unit_tests/visualization/test_plot_psf.py +++ b/tests/unit_tests/visualization/test_plot_psf.py @@ -308,7 +308,9 @@ def test_create_psf_vs_offaxis_plot(sample_parameters, tmp_path): plt.close("all") # Verify telescope parameters were applied and simulation was run - mock_telescope_model.overwrite_parameters.assert_called_once_with(sample_parameters) + mock_telescope_model.overwrite_parameters.assert_called_once_with( + sample_parameters, flat_dict=True + ) assert mock_save.call_count >= 1 # At least one save call From 6a466689bf8e8133305b24d4361490741b15d9de Mon Sep 17 00:00:00 2001 From: Gernot Maier Date: Fri, 30 Jan 2026 14:41:49 +0100 Subject: [PATCH 2/3] Update src/simtools/model/model_parameter.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/simtools/model/model_parameter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simtools/model/model_parameter.py b/src/simtools/model/model_parameter.py index f69b589671..55a0c2114b 100644 --- a/src/simtools/model/model_parameter.py +++ b/src/simtools/model/model_parameter.py @@ -515,9 +515,9 @@ def overwrite_parameters(self, changes, flat_dict=False): return if flat_dict: - self._logger.warning(f"Overwriting parameters with changes: {changes}") + self._logger.debug(f"Overwriting parameters with changes: {changes}") else: - self._logger.warning( + self._logger.debug( f"Overwriting parameters for {key_for_changes} with changes: {changes}" ) From 6a022ed31a6ae743766b0f7580fc008aff779f87 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 2 Feb 2026 15:24:32 +0000 Subject: [PATCH 3/3] typo --- tests/unit_tests/visualization/test_plot_psf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit_tests/visualization/test_plot_psf.py b/tests/unit_tests/visualization/test_plot_psf.py index 53c27c4b80..baa5c8e39b 100644 --- a/tests/unit_tests/visualization/test_plot_psf.py +++ b/tests/unit_tests/visualization/test_plot_psf.py @@ -311,9 +311,9 @@ def test_create_psf_vs_offaxis_plot(sample_parameters, tmp_path): mock_telescope_model.overwrite_parameters.assert_called_once_with( sample_parameters, flat_dict=True ) - assert mock_save.call_count >= 1 # At least one save call + assert mock_save_figure.call_count >= 1 # At least one save call + - def test_plot_psf_histogram_returns_none_when_not_configured(tmp_path): args_dict = {"output_path": str(tmp_path)} assert plot_psf.plot_psf_histogram([10.0], [11.0], args_dict) is None