Skip to content

Commit

Permalink
- Allows to read thermals
Browse files Browse the repository at this point in the history
- Add study sample
  • Loading branch information
killian-scalian committed Oct 2, 2024
1 parent 2c33a22 commit 7c37948
Show file tree
Hide file tree
Showing 71 changed files with 54,510 additions and 75 deletions.
15 changes: 10 additions & 5 deletions src/antares/model/study.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,15 @@ def create_study_api(
response = wrapper.post(url)
study_id = response.json()

study_settings = _returns_study_settings(base_url, study_id, wrapper, False, settings)
study_settings = _returns_study_settings(
base_url, study_id, wrapper, False, settings
)

except APIError as e:
raise StudyCreationError(study_name, e.message) from e
return Study(study_name, version, ServiceFactory(api_config, study_id), study_settings)
return Study(
study_name, version, ServiceFactory(api_config, study_id), study_settings
)


def _verify_study_already_exists(study_directory: Path) -> None:
Expand Down Expand Up @@ -184,14 +188,15 @@ def _directory_not_exists(local_path: Path) -> None:
if local_path is None or not os.path.exists(local_path):
raise ValueError(f"Provided directory {local_path} does not exist.")

_directory_not_exists(local_config.local_path)
study_directory = local_config.local_path / study_name
local_path = Path(local_config.local_path)
_directory_not_exists(local_path)
study_directory = local_path / study_name
_directories_can_be_read(study_directory)

return Study(
name=study_name,
version=version,
service_factory=ServiceReader(config=local_config, study_name=study_name),
service_factory=ServiceReader(config=local_config, study_name=Path(study_name)),
mode="read",
)

Expand Down
134 changes: 99 additions & 35 deletions src/antares/service/local_services/area_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import os
from configparser import ConfigParser
from typing import Optional, Dict, List, Any

import pandas as pd

from antares.config.local_configuration import LocalConfiguration
Expand Down Expand Up @@ -79,7 +78,9 @@ def _sets_ini_content() -> ConfigParser:


class AreaLocalService(BaseAreaService):
def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None:
def __init__(
self, config: LocalConfiguration, study_name: str, **kwargs: Any
) -> None:
super().__init__(**kwargs)
self.config = config
self.study_name = study_name
Expand All @@ -99,9 +100,13 @@ def create_thermal_cluster(
thermal_name: str,
properties: Optional[ThermalClusterProperties] = None,
) -> ThermalCluster:
local_thermal_properties = ThermalClusterPropertiesLocal(thermal_name, properties)
local_thermal_properties = ThermalClusterPropertiesLocal(
thermal_name, properties
)

list_ini = IniFile(self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id)
list_ini = IniFile(
self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id
)
list_ini.add_section(local_thermal_properties.list_ini_fields)
list_ini.write_ini_file(sort_sections=True)

Expand Down Expand Up @@ -134,7 +139,9 @@ def create_renewable_cluster(
) -> RenewableCluster:
local_properties = RenewableClusterPropertiesLocal(renewable_name, properties)

list_ini = IniFile(self.config.study_path, IniFileTypes.RENEWABLES_LIST_INI, area_name=area_id)
list_ini = IniFile(
self.config.study_path, IniFileTypes.RENEWABLES_LIST_INI, area_name=area_id
)
list_ini.add_section(local_properties.ini_fields)
list_ini.write_ini_file()

Expand All @@ -151,9 +158,13 @@ def create_st_storage(
st_storage_name: str,
properties: Optional[STStorageProperties] = None,
) -> STStorage:
local_st_storage_properties = STStoragePropertiesLocal(st_storage_name, properties)
local_st_storage_properties = STStoragePropertiesLocal(
st_storage_name, properties
)

list_ini = IniFile(self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id)
list_ini = IniFile(
self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id
)
list_ini.add_section(local_st_storage_properties.list_ini_fields)
list_ini.write_ini_file(sort_sections=True)

Expand All @@ -166,22 +177,30 @@ def create_st_storage(

def create_wind(self, area: Area, series: Optional[pd.DataFrame]) -> Wind:
series = series if series is not None else pd.DataFrame([])
local_file = TimeSeriesFile(TimeSeriesFileType.WIND, self.config.study_path, area.id, series)
local_file = TimeSeriesFile(
TimeSeriesFileType.WIND, self.config.study_path, area.id, series
)
return Wind(series, local_file)

def create_reserves(self, area: Area, series: Optional[pd.DataFrame]) -> Reserves:
series = series if series is not None else pd.DataFrame([])
local_file = TimeSeriesFile(TimeSeriesFileType.RESERVES, self.config.study_path, area.id, series)
local_file = TimeSeriesFile(
TimeSeriesFileType.RESERVES, self.config.study_path, area.id, series
)
return Reserves(series, local_file)

def create_solar(self, area: Area, series: Optional[pd.DataFrame]) -> Solar:
series = series if series is not None else pd.DataFrame([])
local_file = TimeSeriesFile(TimeSeriesFileType.SOLAR, self.config.study_path, area.id, series)
local_file = TimeSeriesFile(
TimeSeriesFileType.SOLAR, self.config.study_path, area.id, series
)
return Solar(series, local_file)

def create_misc_gen(self, area: Area, series: Optional[pd.DataFrame]) -> MiscGen:
series = series if series is not None else pd.DataFrame([])
local_file = TimeSeriesFile(TimeSeriesFileType.MISC_GEN, self.config.study_path, area.id, series)
local_file = TimeSeriesFile(
TimeSeriesFileType.MISC_GEN, self.config.study_path, area.id, series
)
return MiscGen(series, local_file)

def create_hydro(
Expand Down Expand Up @@ -240,8 +259,12 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool:
with open(list_path, "r") as list_file:
list_file_content = list_file.read()
if _line_exists_in_file(list_file_content, area_to_add):
raise ValueError(f"The Area '{area_name}' already exists in the study {self.study_name}.")
updated_list = sorted(list_file_content.splitlines(keepends=True) + [area_to_add])
raise ValueError(
f"The Area '{area_name}' already exists in the study {self.study_name}."
)
updated_list = sorted(
list_file_content.splitlines(keepends=True) + [area_to_add]
)
else:
updated_list = [area_to_add]

Expand All @@ -252,32 +275,42 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool:
# TODO: Handle districts in sets.ini later
sets_ini_content = _sets_ini_content()

with (self.config.study_path / IniFileTypes.AREAS_SETS_INI.value).open("w") as sets_ini:
with (self.config.study_path / IniFileTypes.AREAS_SETS_INI.value).open(
"w"
) as sets_ini:
sets_ini_content.write(sets_ini)

local_properties = AreaPropertiesLocal(properties) if properties else AreaPropertiesLocal()
local_properties = (
AreaPropertiesLocal(properties) if properties else AreaPropertiesLocal()
)

adequacy_patch_ini = IniFile(self.config.study_path, IniFileTypes.AREA_ADEQUACY_PATCH_INI, area_name)
adequacy_patch_ini = IniFile(
self.config.study_path, IniFileTypes.AREA_ADEQUACY_PATCH_INI, area_name
)
adequacy_patch_ini.add_section(local_properties.adequacy_patch_mode())
adequacy_patch_ini.write_ini_file()

optimization_ini = ConfigParser()
optimization_ini.read_dict(local_properties.model_dump(by_alias=True, exclude_none=True))
optimization_ini.read_dict(
local_properties.model_dump(by_alias=True, exclude_none=True)
)

with open(new_area_directory / "optimization.ini", "w") as optimization_ini_file:
with open(
new_area_directory / "optimization.ini", "w"
) as optimization_ini_file:
optimization_ini.write(optimization_ini_file)

areas_ini = IniFile(self.config.study_path, IniFileTypes.THERMAL_AREAS_INI)
if not areas_ini.ini_dict:
areas_ini.add_section({"unserverdenergycost": {}})
areas_ini.add_section({"spilledenergycost": {}})
areas_ini.write_ini_file()
areas_ini.parsed_ini["unserverdenergycost"][area_name] = local_properties.nodal_optimization[
"average-unsupplied-energy-cost"
]
areas_ini.parsed_ini["spilledenergycost"][area_name] = local_properties.nodal_optimization[
"average-spilled-energy-cost"
]
areas_ini.parsed_ini["unserverdenergycost"][
area_name
] = local_properties.nodal_optimization["average-unsupplied-energy-cost"]
areas_ini.parsed_ini["spilledenergycost"][
area_name
] = local_properties.nodal_optimization["average-spilled-energy-cost"]
areas_ini.write_ini_file()

local_ui = AreaUiLocal(ui) if ui else AreaUiLocal()
Expand Down Expand Up @@ -305,16 +338,22 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool:
def delete_area(self, area: Area) -> None:
raise NotImplementedError

def update_area_properties(self, area: Area, properties: AreaProperties) -> AreaProperties:
def update_area_properties(
self, area: Area, properties: AreaProperties
) -> AreaProperties:
raise NotImplementedError

def update_area_ui(self, area: Area, ui: AreaUi) -> AreaUi:
raise NotImplementedError

def delete_thermal_clusters(self, area: Area, thermal_clusters: List[ThermalCluster]) -> None:
def delete_thermal_clusters(
self, area: Area, thermal_clusters: List[ThermalCluster]
) -> None:
raise NotImplementedError

def delete_renewable_clusters(self, area: Area, renewable_clusters: List[RenewableCluster]) -> None:
def delete_renewable_clusters(
self, area: Area, renewable_clusters: List[RenewableCluster]
) -> None:
raise NotImplementedError

def delete_st_storages(self, area: Area, storages: List[STStorage]) -> None:
Expand All @@ -332,9 +371,13 @@ def read_thermal_cluster(
thermal_name: str,
properties: Optional[ThermalClusterProperties] = None,
) -> ThermalCluster:
local_thermal_properties = ThermalClusterPropertiesLocal(thermal_name, properties)
local_thermal_properties = ThermalClusterPropertiesLocal(
thermal_name, properties
)

list_ini = IniFile(self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id)
list_ini = IniFile(
self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id
)
list_ini.add_section(local_thermal_properties.list_ini_fields)
list_ini.write_ini_file(sort_sections=True)

Expand Down Expand Up @@ -372,7 +415,9 @@ def read_st_storage(
) -> STStorage:
local_st_storage_properties = STStoragePropertiesLocal(st_storage_name, properties)

list_ini = IniFile(self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id)
list_ini = IniFile(
self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id
)
list_ini.add_section(local_st_storage_properties.list_ini_fields)
list_ini.write_ini_file(sort_sections=True)

Expand Down Expand Up @@ -416,11 +461,10 @@ def read_hydro(

return Hydro(self, area_id, local_hydro_properties.yield_hydro_properties())

def read_area(self, area_name: str, area_id: str) -> Area:
def read_area(self, area_name: str) -> Area:
"""
Args:
area_name: area to be added to study
area_id: area id. If not provided, default values will be used.
Returns: area object if success or Error if area can not be
read
Expand All @@ -437,8 +481,28 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool:
"""
return line_to_add.strip() in file_content.split("\n")

existing_path = self._config.local_path
existing_path = self.config.local_path
study_path = existing_path / self.study_name
list_ini = IniFile(self.config.study_path, IniFileTypes.AREAS_SETS_INI)
optimization_ini = IniFile(
study_path, IniFileTypes.AREA_OPTIMIZATION_INI, area_name
).parsed_ini
dict_optimization = {
section: {key: f"{value}" for key, value in optimization_ini.items(section)}
for section in optimization_ini.sections()
}

ui_ini = IniFile(study_path, IniFileTypes.AREA_UI_INI, area_name).parsed_ini
dict_ui = {
section: {key: f"{value}" for key, value in ui_ini.items(section)}
for section in ui_ini.sections()
}

patch_ini = IniFile(
study_path, IniFileTypes.AREA_ADEQUACY_PATCH_INI, area_name
).parsed_ini
dict_adequacy_patch = {
section: {key: f"{value}" for key, value in patch_ini.items(section)}
for section in patch_ini.sections()
}

return {}
return [dict_optimization, dict_ui, dict_adequacy_patch]
20 changes: 15 additions & 5 deletions src/antares/service/local_services/study_local.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Optional, Any
import os
import json
from pathlib import Path

from antares.config.local_configuration import LocalConfiguration
from antares.model.binding_constraint import BindingConstraint
Expand All @@ -9,7 +10,9 @@


class StudyLocalService(BaseStudyService):
def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None:
def __init__(
self, config: LocalConfiguration, study_name: Path, **kwargs: Any
) -> None:
super().__init__(**kwargs)
self._config = config
self._study_name = study_name
Expand All @@ -33,21 +36,28 @@ def delete(self, children: bool) -> None:

def read_areas(self) -> json:
local_path = self._config.local_path
patch_path = local_path / self._study_name / "patch.json"

patch_path = local_path / self._study_name / Path("patch.json")
if not os.path.exists(patch_path):
return json.loads(f"Le fichier {patch_path} n'existe pas dans le dossier {local_path / self._study_name}")
return json.loads(
f"Le fichier {patch_path} n'existe pas dans le dossier {local_path / self._study_name}"
)
try:
with open(patch_path, "r") as file:
content = file.read()
try:
data = json.loads(content)
except json.JSONDecodeError:
return json.loads(f"Le fichier {patch_path} ne contient pas du JSON valide")
return json.loads(
f"Le fichier {patch_path} ne contient pas du JSON valide"
)
if "areas" in data:
areas = data["areas"]
if isinstance(areas, dict):
return list(areas.keys())
else:
return json.loads(f"The key 'areas' n'existe pas dans le fichier JSON")
return json.loads(
f"The key 'areas' n'existe pas dans le fichier JSON"
)
except IOError:
return f"Impossible de lire le fichier {patch_path}"
Loading

0 comments on commit 7c37948

Please sign in to comment.