Skip to content

Commit

Permalink
conflits resolved
Browse files Browse the repository at this point in the history
  • Loading branch information
vargastat authored and MartinBelthle committed Dec 4, 2024
1 parent 795d14d commit 4973fe0
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 31 deletions.
23 changes: 20 additions & 3 deletions src/antares/model/study.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ def __init__(
self._settings = DefaultStudySettings.model_validate(settings if settings is not None else StudySettings())
self._areas: Dict[str, Area] = dict()
self._links: Dict[str, Link] = dict()
self._binding_constraints: Dict[str, BindingConstraint] = dict()

@property
def service(self) -> BaseStudyService:
Expand All @@ -229,7 +230,7 @@ def get_settings(self) -> DefaultStudySettings:
return self._settings

def get_binding_constraints(self) -> MappingProxyType[str, BindingConstraint]:
return MappingProxyType(self._binding_constraints_service.binding_constraints)
return MappingProxyType(self._binding_constraints)

def create_area(
self, area_name: str, *, properties: Optional[AreaProperties] = None, ui: Optional[AreaUi] = None
Expand Down Expand Up @@ -269,9 +270,25 @@ def create_binding_constraint(
equal_term_matrix: Optional[pd.DataFrame] = None,
greater_term_matrix: Optional[pd.DataFrame] = None,
) -> BindingConstraint:
return self._binding_constraints_service.create_binding_constraint(
"""
Create a new binding constraint and store it.
Args:
name (str): The name of the binding constraint.
properties (Optional[BindingConstraintProperties]): Optional properties for the constraint.
terms (Optional[List[ConstraintTerm]]): Optional list of terms for the constraint.
less_term_matrix (Optional[pd.DataFrame]): Optional less-than term matrix.
equal_term_matrix (Optional[pd.DataFrame]): Optional equality term matrix.
greater_term_matrix (Optional[pd.DataFrame]): Optional greater-than term matrix.
Returns:
BindingConstraint: The created binding constraint.
"""
binding_constraint = self._binding_constraints_service.create_binding_constraint(
name, properties, terms, less_term_matrix, equal_term_matrix, greater_term_matrix
)
self._binding_constraints[binding_constraint.name] = binding_constraint
return binding_constraint

def update_settings(self, settings: StudySettings) -> None:
new_settings = self._study_service.update_study_settings(settings)
Expand All @@ -280,7 +297,7 @@ def update_settings(self, settings: StudySettings) -> None:

def delete_binding_constraint(self, constraint: BindingConstraint) -> None:
self._study_service.delete_binding_constraint(constraint)
self._binding_constraints_service.binding_constraints.pop(constraint.id)
self._binding_constraints.pop(constraint.id)

def delete(self, children: bool = False) -> None:
self._study_service.delete(children)
Expand Down
2 changes: 0 additions & 2 deletions src/antares/service/api_services/binding_constraint_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def __init__(self, config: APIconf, study_id: str) -> None:
self.study_id = study_id
self._wrapper = RequestWrapper(self.api_config.set_up_api_conf())
self._base_url = f"{self.api_config.get_host()}/api/v1"
self.binding_constraints = {}

def create_binding_constraint(
self,
Expand Down Expand Up @@ -105,7 +104,6 @@ def create_binding_constraint(
raise BindingConstraintCreationError(name, e.message) from e

constraint = BindingConstraint(name, self, bc_properties, bc_terms)
self.binding_constraints[constraint.id] = constraint

return constraint

Expand Down
86 changes: 67 additions & 19 deletions src/antares/service/local_services/binding_constraint_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.

from typing import Any, Optional

import numpy as np
Expand All @@ -22,6 +21,7 @@
BindingConstraintFrequency,
BindingConstraintOperator,
BindingConstraintProperties,
BindingConstraintPropertiesLocal,
ConstraintMatrixName,
ConstraintTerm,
)
Expand All @@ -37,7 +37,6 @@ def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -
self.config = config
self.study_name = study_name
self.ini_file = IniFile(self.config.study_path, IniFileTypes.BINDING_CONSTRAINTS_INI)
self.binding_constraints = {}

def create_binding_constraint(
self,
Expand All @@ -54,17 +53,10 @@ def create_binding_constraint(
properties=properties,
terms=terms,
)
if constraint.id in self.binding_constraints:
raise BindingConstraintCreationError(
constraint_name=name, message=f"A binding constraint with the name '{name}' already exists."
)
constraint.properties = constraint.local_properties.yield_binding_constraint_properties()

# Add binding constraints
self.binding_constraints[constraint.id] = constraint
self._write_binding_constraint_ini()
self._write_binding_constraint_ini(constraint.properties, name, name, terms)

# Add constraint time series
self._store_time_series(constraint, less_term_matrix, equal_term_matrix, greater_term_matrix)

return constraint
Expand Down Expand Up @@ -103,20 +95,76 @@ def _check_if_empty_ts(time_step: BindingConstraintFrequency, time_series: Optio
time_series_length = (365 * 24 + 24) if time_step == BindingConstraintFrequency.HOURLY else 366
return time_series if time_series is not None else pd.DataFrame(np.zeros([time_series_length, 1]))

def _write_binding_constraint_ini(self) -> None:
binding_constraints_ini_content = {
idx: idx_constraint.local_properties.list_ini_fields
for idx, idx_constraint in enumerate(self.binding_constraints.values())
}
self.ini_file.ini_dict = binding_constraints_ini_content
def _write_binding_constraint_ini(
self,
properties: BindingConstraintProperties,
constraint_name: str,
constraint_id: str,
terms: Optional[list[ConstraintTerm]] = None,
) -> None:
"""
Write a single binding constraint to the INI file, reconstructing a full BindingConstraintPropertiesLocal instance.
Args:
properties (BindingConstraintProperties): Basic properties of the binding constraint.
constraint_name (str): The name of the constraint.
constraint_id (str): The ID of the constraint.
terms (dict[str, ConstraintTerm], optional): Terms applying to the binding constraint. Defaults to None.
Raises:
BindingConstraintCreationError: If a binding constraint with the same name already exists in the INI file.
"""

current_ini_content = self.ini_file.ini_dict or {}

if constraint_name in current_ini_content:
if terms in [None, {}]:
raise BindingConstraintCreationError(
constraint_name=constraint_name,
message=f"A binding constraint with the name {constraint_name} already exists with terms.",
)

terms_dict = {term.id: term for term in terms} if terms else {}

full_properties = BindingConstraintPropertiesLocal(
constraint_name=constraint_name, constraint_id=constraint_id, terms=terms_dict, **properties.model_dump()
)

current_ini_content = self.ini_file.ini_dict or {}

current_ini_content[full_properties.constraint_name] = full_properties.list_ini_fields

self.ini_file.ini_dict = current_ini_content

self.ini_file.write_ini_file()

def add_constraint_terms(self, constraint: BindingConstraint, terms: list[ConstraintTerm]) -> list[ConstraintTerm]:
new_terms = constraint.local_properties.terms | {
term.id: term for term in terms if term.id not in constraint.get_terms()
"""
Add terms to a binding constraint and update the INI file.
Args:
constraint (BindingConstraint): The binding constraint to update.
terms (list[ConstraintTerm]): A list of new terms to add.
Returns:
list[ConstraintTerm]: The updated list of terms.
"""

new_terms = {
**constraint.local_properties.terms, # Existing terms
**{term.id: term for term in terms if term.id not in constraint.get_terms()}, # New terms
}

constraint.local_properties.terms = new_terms
self._write_binding_constraint_ini()

list(new_terms.values())

self._write_binding_constraint_ini(
properties=constraint.properties,
constraint_name=constraint.name,
constraint_id=constraint.id,
terms=list(new_terms.values()),
)

return list(new_terms.values())

def delete_binding_constraint_term(self, constraint_id: str, term_id: str) -> None:
Expand Down
14 changes: 7 additions & 7 deletions tests/antares/services/local_services/test_study.py
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,7 @@ def test_creating_duplicate_area_name_errors(self, local_study_w_areas):
# Then
with pytest.raises(
AreaCreationError,
match=f"Could not create the area {area_to_create}: There is already an area '{area_to_create}' in the study '{local_study_w_areas.name}'",
match=f"Could not create the area {area_to_create}: There is already an area '{area_to_create}' in the study '{local_study_w_areas.name}",
):
local_study_w_areas.create_area(area_to_create)

Expand Down Expand Up @@ -2071,7 +2071,7 @@ def test_duplicate_name_errors(self, local_study_with_constraint):
# Then
with pytest.raises(
BindingConstraintCreationError,
match=f"Could not create the binding constraint {binding_constraint_name}: A binding constraint with the name '{binding_constraint_name}' already exists.",
match=f"Could not create the binding constraint {binding_constraint_name}: A binding constraint with the name {binding_constraint_name} already exists.",
):
local_study_with_constraint.create_binding_constraint(name=binding_constraint_name)

Expand Down Expand Up @@ -2099,7 +2099,7 @@ def test_constraints_ini_have_correct_default_content(
self, local_study_with_constraint, test_constraint, default_constraint_properties
):
# Given
expected_ini_contents = """[0]
expected_ini_contents = """[test constraint]
name = test constraint
id = test constraint
enabled = true
Expand Down Expand Up @@ -2133,7 +2133,7 @@ def test_constraints_and_ini_have_custom_properties(self, local_study_with_const
filter_synthesis="monthly",
group="test group",
)
expected_ini_content = """[0]
expected_ini_content = """[test constraint]
name = test constraint
id = test constraint
enabled = true
Expand All @@ -2143,7 +2143,7 @@ def test_constraints_and_ini_have_custom_properties(self, local_study_with_const
filter-synthesis = hourly
group = default
[1]
[test constraint two]
name = test constraint two
id = test constraint two
enabled = false
Expand Down Expand Up @@ -2176,7 +2176,7 @@ def test_constraint_can_add_term(self, test_constraint):

def test_constraint_term_and_ini_have_correct_defaults(self, local_study_with_constraint, test_constraint):
# Given
expected_ini_contents = """[0]
expected_ini_contents = """[test constraint]
name = test constraint
id = test constraint
enabled = true
Expand All @@ -2200,7 +2200,7 @@ def test_constraint_term_with_offset_and_ini_have_correct_values(
self, local_study_with_constraint, test_constraint
):
# Given
expected_ini_contents = """[0]
expected_ini_contents = """[test constraint]
name = test constraint
id = test constraint
enabled = true
Expand Down

0 comments on commit 4973fe0

Please sign in to comment.