From 764edfffcbf0bf59ed3e50cd606cd9e61fab06c0 Mon Sep 17 00:00:00 2001 From: Sigurd Borge Date: Fri, 18 Oct 2024 20:19:54 +0200 Subject: [PATCH] Added default Thematic Trimming --- src/antares/model/settings/study_settings.py | 2 +- .../model/settings/thematic_trimming.py | 208 ++++++++++-------- .../services/local_services/test_study.py | 126 +++++++++++ 3 files changed, 239 insertions(+), 97 deletions(-) diff --git a/src/antares/model/settings/study_settings.py b/src/antares/model/settings/study_settings.py index c89ef87c..0d97fadc 100644 --- a/src/antares/model/settings/study_settings.py +++ b/src/antares/model/settings/study_settings.py @@ -25,7 +25,7 @@ class DefaultStudySettings(BaseModel): general_parameters: DefaultGeneralParameters = DefaultGeneralParameters() - thematic_trimming_parameters: ThematicTrimmingParameters = ThematicTrimmingParameters() + thematic_trimming_parameters: Optional[DefaultThematicTrimmingParameters] = None # These parameters are listed under the [variables selection] section in the .ini file. # They are required if thematic-trimming is set to true. # https://antares-simulator.readthedocs.io/en/latest/user-guide/solver/04-parameters/#variables-selection-parameters diff --git a/src/antares/model/settings/thematic_trimming.py b/src/antares/model/settings/thematic_trimming.py index bb8e2bc8..87de0675 100644 --- a/src/antares/model/settings/thematic_trimming.py +++ b/src/antares/model/settings/thematic_trimming.py @@ -9,115 +9,131 @@ # SPDX-License-Identifier: MPL-2.0 # # This file is part of the Antares project. - -from typing import Optional +from enum import Enum from pydantic import BaseModel from pydantic.alias_generators import to_camel +from antares.tools.all_optional_meta import all_optional_model + -class ThematicTrimmingParameters(BaseModel, alias_generator=to_camel): +class DefaultThematicTrimmingParameters(BaseModel, alias_generator=to_camel): """ This class manages the configuration of result filtering in a simulation. This table allows the user to enable or disable specific variables before running a simulation. """ - ov_cost: Optional[bool] = None - op_cost: Optional[bool] = None - mrg_price: Optional[bool] = None - co2_emis: Optional[bool] = None - dtg_by_plant: Optional[bool] = None - balance: Optional[bool] = None - row_bal: Optional[bool] = None - psp: Optional[bool] = None - misc_ndg: Optional[bool] = None - load: Optional[bool] = None - h_ror: Optional[bool] = None - wind: Optional[bool] = None - solar: Optional[bool] = None - nuclear: Optional[bool] = None - lignite: Optional[bool] = None - coal: Optional[bool] = None - gas: Optional[bool] = None - oil: Optional[bool] = None - mix_fuel: Optional[bool] = None - misc_dtg: Optional[bool] = None - h_stor: Optional[bool] = None - h_pump: Optional[bool] = None - h_lev: Optional[bool] = None - h_infl: Optional[bool] = None - h_ovfl: Optional[bool] = None - h_val: Optional[bool] = None - h_cost: Optional[bool] = None - unsp_enrg: Optional[bool] = None - spil_enrg: Optional[bool] = None - lold: Optional[bool] = None - lolp: Optional[bool] = None - avl_dtg: Optional[bool] = None - dtg_mrg: Optional[bool] = None - max_mrg: Optional[bool] = None - np_cost: Optional[bool] = None - np_cost_by_plant: Optional[bool] = None - nodu: Optional[bool] = None - nodu_by_plant: Optional[bool] = None - flow_lin: Optional[bool] = None - ucap_lin: Optional[bool] = None - loop_flow: Optional[bool] = None - flow_quad: Optional[bool] = None - cong_fee_alg: Optional[bool] = None - cong_fee_abs: Optional[bool] = None - marg_cost: Optional[bool] = None - cong_prob_plus: Optional[bool] = None - cong_prob_minus: Optional[bool] = None - hurdle_cost: Optional[bool] = None + ov_cost: bool = True + op_cost: bool = True + mrg_price: bool = True + co2_emis: bool = True + dtg_by_plant: bool = True + balance: bool = True + row_bal: bool = True + psp: bool = True + misc_ndg: bool = True + load: bool = True + h_ror: bool = True + wind: bool = True + solar: bool = True + nuclear: bool = True + lignite: bool = True + coal: bool = True + gas: bool = True + oil: bool = True + mix_fuel: bool = True + misc_dtg: bool = True + h_stor: bool = True + h_pump: bool = True + h_lev: bool = True + h_infl: bool = True + h_ovfl: bool = True + h_val: bool = True + h_cost: bool = True + unsp_enrg: bool = True + spil_enrg: bool = True + lold: bool = True + lolp: bool = True + avl_dtg: bool = True + dtg_mrg: bool = True + max_mrg: bool = True + np_cost: bool = True + np_cost_by_plant: bool = True + nodu: bool = True + nodu_by_plant: bool = True + flow_lin: bool = True + ucap_lin: bool = True + loop_flow: bool = True + flow_quad: bool = True + cong_fee_alg: bool = True + cong_fee_abs: bool = True + marg_cost: bool = True + cong_prob_plus: bool = True + cong_prob_minus: bool = True + hurdle_cost: bool = True # since v8.1 - res_generation_by_plant: Optional[bool] = None - misc_dtg_2: Optional[bool] = None - misc_dtg_3: Optional[bool] = None - misc_dtg_4: Optional[bool] = None - wind_offshore: Optional[bool] = None - wind_onshore: Optional[bool] = None - solar_concrt: Optional[bool] = None - solar_pv: Optional[bool] = None - solar_rooft: Optional[bool] = None - renw_1: Optional[bool] = None - renw_2: Optional[bool] = None - renw_3: Optional[bool] = None - renw_4: Optional[bool] = None + res_generation_by_plant: bool = True + misc_dtg_2: bool = True + misc_dtg_3: bool = True + misc_dtg_4: bool = True + wind_offshore: bool = True + wind_onshore: bool = True + solar_concrt: bool = True + solar_pv: bool = True + solar_rooft: bool = True + renw_1: bool = True + renw_2: bool = True + renw_3: bool = True + renw_4: bool = True # since v8.3 - dens: Optional[bool] = None - profit_by_plant: Optional[bool] = None + dens: bool = True + profit_by_plant: bool = True # since v8.6 - sts_inj_by_plant: Optional[bool] = None - sts_withdrawal_by_plant: Optional[bool] = None - sts_lvl_by_plant: Optional[bool] = None - psp_open_injection: Optional[bool] = None - psp_open_withdrawal: Optional[bool] = None - psp_open_level: Optional[bool] = None - psp_closed_injection: Optional[bool] = None - psp_closed_withdrawal: Optional[bool] = None - psp_closed_level: Optional[bool] = None - pondage_injection: Optional[bool] = None - pondage_withdrawal: Optional[bool] = None - pondage_level: Optional[bool] = None - battery_injection: Optional[bool] = None - battery_withdrawal: Optional[bool] = None - battery_level: Optional[bool] = None - other1_injection: Optional[bool] = None - other1_withdrawal: Optional[bool] = None - other1_level: Optional[bool] = None - other2_injection: Optional[bool] = None - other2_withdrawal: Optional[bool] = None - other2_level: Optional[bool] = None - other3_injection: Optional[bool] = None - other3_withdrawal: Optional[bool] = None - other3_level: Optional[bool] = None - other4_injection: Optional[bool] = None - other4_withdrawal: Optional[bool] = None - other4_level: Optional[bool] = None - other5_injection: Optional[bool] = None - other5_withdrawal: Optional[bool] = None - other5_level: Optional[bool] = None + sts_inj_by_plant: bool = True + sts_withdrawal_by_plant: bool = True + sts_lvl_by_plant: bool = True + psp_open_injection: bool = True + psp_open_withdrawal: bool = True + psp_open_level: bool = True + psp_closed_injection: bool = True + psp_closed_withdrawal: bool = True + psp_closed_level: bool = True + pondage_injection: bool = True + pondage_withdrawal: bool = True + pondage_level: bool = True + battery_injection: bool = True + battery_withdrawal: bool = True + battery_level: bool = True + other1_injection: bool = True + other1_withdrawal: bool = True + other1_level: bool = True + other2_injection: bool = True + other2_withdrawal: bool = True + other2_level: bool = True + other3_injection: bool = True + other3_withdrawal: bool = True + other3_level: bool = True + other4_injection: bool = True + other4_withdrawal: bool = True + other4_level: bool = True + other5_injection: bool = True + other5_withdrawal: bool = True + other5_level: bool = True # since v8.8 sts_cashflow_by_cluster: Optional[bool] = None + sts_cashflow_by_cluster: bool = True + + @property + def selected_vars_reset(self) -> bool: + return sum([getattr(self, field) for field in self.model_fields]) > (len(self.model_fields) / 2) + + +@all_optional_model +class ThematicTrimmingParameters(DefaultThematicTrimmingParameters): + pass + + +class ThematicTrimmingParametersLocal(DefaultThematicTrimmingParameters): + pass + diff --git a/tests/antares/services/local_services/test_study.py b/tests/antares/services/local_services/test_study.py index e46e9a52..9e939af3 100644 --- a/tests/antares/services/local_services/test_study.py +++ b/tests/antares/services/local_services/test_study.py @@ -64,6 +64,7 @@ BuildingMode, DefaultGeneralParameters, GeneralParameters, + GeneralParametersLocal, Mode, Month, WeekDay, @@ -77,6 +78,7 @@ ) from antares.model.settings.playlist_parameters import PlaylistData, PlaylistParameters from antares.model.settings.study_settings import DefaultStudySettings, StudySettingsLocal +from antares.model.settings.thematic_trimming import DefaultThematicTrimmingParameters, ThematicTrimmingParametersLocal from antares.model.study import create_study_local from antares.service.local_services.area_local import AreaLocalService from antares.service.local_services.link_local import LinkLocalService @@ -506,6 +508,130 @@ def test_local_study_with_playlist_has_correct_defaults(self, tmp_path): assert actual_playlist_parameters_dict == expected_playlist_parameters_dict assert actual_playlist_parameters == expected_playlist_parameters + def test_local_study_has_correct_thematic_trimming_parameters(self, tmp_path): + # Given + expected_thematic_trimming_parameters = ThematicTrimmingParametersLocal.model_validate( + { + "ov_cost": True, + "op_cost": True, + "mrg_price": True, + "co2_emis": True, + "dtg_by_plant": True, + "balance": True, + "row_bal": True, + "psp": True, + "misc_ndg": True, + "load": True, + "h_ror": True, + "wind": True, + "solar": True, + "nuclear": True, + "lignite": True, + "coal": True, + "gas": True, + "oil": True, + "mix_fuel": True, + "misc_dtg": True, + "h_stor": True, + "h_pump": True, + "h_lev": True, + "h_infl": True, + "h_ovfl": True, + "h_val": True, + "h_cost": True, + "unsp_enrg": True, + "spil_enrg": True, + "lold": True, + "lolp": True, + "avl_dtg": True, + "dtg_mrg": True, + "max_mrg": True, + "np_cost": True, + "np_cost_by_plant": True, + "nodu": True, + "nodu_by_plant": True, + "flow_lin": True, + "ucap_lin": True, + "loop_flow": True, + "flow_quad": True, + "cong_fee_alg": True, + "cong_fee_abs": True, + "marg_cost": True, + "cong_prob_plus": True, + "cong_prob_minus": True, + "hurdle_cost": True, + "res_generation_by_plant": True, + "misc_dtg_2": True, + "misc_dtg_3": True, + "misc_dtg_4": True, + "wind_offshore": True, + "wind_onshore": True, + "solar_concrt": True, + "solar_pv": True, + "solar_rooft": True, + "renw_1": True, + "renw_2": True, + "renw_3": True, + "renw_4": True, + "dens": True, + "profit_by_plant": True, + "sts_inj_by_plant": True, + "sts_withdrawal_by_plant": True, + "sts_lvl_by_plant": True, + "psp_open_injection": True, + "psp_open_withdrawal": True, + "psp_open_level": True, + "psp_closed_injection": True, + "psp_closed_withdrawal": True, + "psp_closed_level": True, + "pondage_injection": True, + "pondage_withdrawal": True, + "pondage_level": True, + "battery_injection": True, + "battery_withdrawal": True, + "battery_level": True, + "other1_injection": True, + "other1_withdrawal": True, + "other1_level": True, + "other2_injection": True, + "other2_withdrawal": True, + "other2_level": True, + "other3_injection": True, + "other3_withdrawal": True, + "other3_level": True, + "other4_injection": True, + "other4_withdrawal": True, + "other4_level": True, + "other5_injection": True, + "other5_withdrawal": True, + "other5_level": True, + "sts_cashflow_by_cluster": True, + } + ) + expected_study_settings = StudySettingsLocal( + general_parameters=GeneralParametersLocal(thematic_trimming=True), + thematic_trimming_parameters=expected_thematic_trimming_parameters, + ) + thematic_trimming_study = create_study_local( + "test_study", + "880", + LocalConfiguration(tmp_path, "test_study"), + StudySettingsLocal( + general_parameters=GeneralParametersLocal(thematic_trimming=True), + thematic_trimming_parameters=ThematicTrimmingParametersLocal(), + ), + ) + + # When + actual_thematic_trimming_parameters = DefaultThematicTrimmingParameters.model_validate( + thematic_trimming_study.get_settings().thematic_trimming_parameters + ) + actual_study_settings = DefaultStudySettings.model_validate(thematic_trimming_study.get_settings()) + + # Then + assert actual_thematic_trimming_parameters == expected_thematic_trimming_parameters + assert actual_study_settings == expected_study_settings + class TestCreateArea: def test_areas_sets_ini_content(self, tmp_path, local_study):