Skip to content

Commit

Permalink
Merge branch 'main' into feat/run_studies
Browse files Browse the repository at this point in the history
  • Loading branch information
salemsd authored Dec 13, 2024
2 parents 5a86131 + f04bf8b commit ba5854d
Show file tree
Hide file tree
Showing 17 changed files with 453 additions and 170 deletions.
12 changes: 12 additions & 0 deletions src/antares/exceptions/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,18 @@ def __init__(self, area_id: str, matrix_type: str, message: str) -> None:
super().__init__(self.message)


class LinkUploadError(Exception):
def __init__(self, area_from_id: str, area_to_id: str, matrix_type: str, message: str) -> None:
self.message = f"Error uploading {matrix_type} matrix for link {area_from_id}/{area_to_id}: {message}"
super().__init__(self.message)


class LinkDownloadError(Exception):
def __init__(self, area_from_id: str, area_to_id: str, matrix_type: str, message: str):
self.message = f"Could not download {matrix_type} matrix for link {area_from_id}/{area_to_id}: {message}"
super().__init__(self.message)


class CustomError(Exception):
def __init__(self, message: str = "Error") -> None:
self.message = message
Expand Down
30 changes: 15 additions & 15 deletions src/antares/model/area.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,66 +286,66 @@ def create_st_storage(self, st_storage_name: str, properties: Optional[STStorage
return storage

def get_load_matrix(self) -> pd.DataFrame:
return self._area_service.get_load_matrix(self)
return self._area_service.get_load_matrix(self.id)

def get_wind_matrix(self) -> pd.DataFrame:
return self._area_service.get_wind_matrix(self)
return self._area_service.get_wind_matrix(self.id)

def get_solar_matrix(self) -> pd.DataFrame:
return self._area_service.get_solar_matrix(self)
return self._area_service.get_solar_matrix(self.id)

def get_reserves_matrix(self) -> pd.DataFrame:
return self._area_service.get_reserves_matrix(self)
return self._area_service.get_reserves_matrix(self.id)

def get_misc_gen_matrix(self) -> pd.DataFrame:
return self._area_service.get_misc_gen_matrix(self)
return self._area_service.get_misc_gen_matrix(self.id)

def delete_thermal_clusters(self, thermal_clusters: List[ThermalCluster]) -> None:
self._area_service.delete_thermal_clusters(self, thermal_clusters)
self._area_service.delete_thermal_clusters(self.id, thermal_clusters)
for cluster in thermal_clusters:
self._thermals.pop(cluster.id)

def delete_thermal_cluster(self, thermal_cluster: ThermalCluster) -> None:
self.delete_thermal_clusters([thermal_cluster])

def delete_renewable_clusters(self, renewable_clusters: List[RenewableCluster]) -> None:
self._area_service.delete_renewable_clusters(self, renewable_clusters)
self._area_service.delete_renewable_clusters(self.id, renewable_clusters)
for cluster in renewable_clusters:
self._renewables.pop(cluster.id)

def delete_renewable_cluster(self, renewable_cluster: RenewableCluster) -> None:
self.delete_renewable_clusters([renewable_cluster])

def delete_st_storages(self, storages: List[STStorage]) -> None:
self._area_service.delete_st_storages(self, storages)
self._area_service.delete_st_storages(self.id, storages)
for storage in storages:
self._st_storages.pop(storage.id)

def delete_st_storage(self, storage: STStorage) -> None:
self.delete_st_storages([storage])

def update_properties(self, properties: AreaProperties) -> None:
new_properties = self._area_service.update_area_properties(self, properties)
new_properties = self._area_service.update_area_properties(self.id, properties)
self._properties = new_properties

def update_ui(self, ui: AreaUi) -> None:
new_ui = self._area_service.update_area_ui(self, ui)
new_ui = self._area_service.update_area_ui(self.id, ui)
self._ui = new_ui

def create_load(self, series: pd.DataFrame) -> None:
self._area_service.create_load(self, series=series)
self._area_service.create_load(self.id, series)

def create_wind(self, series: pd.DataFrame) -> None:
self._area_service.create_wind(self, series=series)
self._area_service.create_wind(self.id, series)

def create_reserves(self, series: pd.DataFrame) -> None:
self._area_service.create_reserves(self, series=series)
self._area_service.create_reserves(self.id, series)

def create_solar(self, series: pd.DataFrame) -> None:
self._area_service.create_solar(self, series=series)
self._area_service.create_solar(self.id, series)

def create_misc_gen(self, series: pd.DataFrame) -> None:
self._area_service.create_misc_gen(self, series=series)
self._area_service.create_misc_gen(self.id, series)

def create_hydro(
self,
Expand Down
15 changes: 12 additions & 3 deletions src/antares/model/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,20 @@ def update_ui(self, ui: LinkUi) -> LinkUi:
self._ui = new_ui
return new_ui

def create_parameters(self, series: pd.DataFrame) -> None:
self._link_service.create_parameters(series, self.area_from_id, self.area_to_id)

def create_capacity_direct(self, series: pd.DataFrame) -> None:
self._link_service.create_capacity_direct(series, self.area_from_id, self.area_to_id)

def create_capacity_indirect(self, series: pd.DataFrame) -> None:
self._link_service.create_capacity_indirect(series, self.area_from_id, self.area_to_id)

def get_capacity_direct(self) -> pd.DataFrame:
return self._link_service.get_capacity_direct(self._area_from, self._area_to)
return self._link_service.get_capacity_direct(self.area_from_id, self.area_to_id)

def get_capacity_indirect(self) -> pd.DataFrame:
return self._link_service.get_capacity_indirect(self._area_from, self._area_to)
return self._link_service.get_capacity_indirect(self.area_from_id, self.area_to_id)

def get_parameters(self) -> pd.DataFrame:
return self._link_service.get_parameters(self._area_from, self._area_to)
return self._link_service.get_parameters(self.area_from_id, self.area_to_id)
2 changes: 1 addition & 1 deletion src/antares/model/study.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def create_area(
return area

def delete_area(self, area: Area) -> None:
self._area_service.delete_area(area)
self._area_service.delete_area(area.id)
self._areas.pop(area.id)

def create_link(
Expand Down
140 changes: 74 additions & 66 deletions src/antares/service/api_services/area_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from antares.model.renewable import RenewableCluster, RenewableClusterProperties
from antares.model.st_storage import STStorage, STStorageProperties
from antares.model.thermal import ThermalCluster, ThermalClusterProperties
from antares.service.api_services.utils import get_matrix, upload_series
from antares.service.base_services import (
BaseAreaService,
BaseRenewableService,
Expand Down Expand Up @@ -353,37 +354,44 @@ def create_st_storage(

return STStorage(self.storage_service, area_id, name, properties)

def _upload_series(self, area: Area, series: pd.DataFrame, path: str, matrix_type: str) -> None:
def create_load(self, area_id: str, series: pd.DataFrame) -> None:
try:
url = f"{self._base_url}/studies/{self.study_id}/raw?path={path}"
array_data = series.to_numpy().tolist()
self._wrapper.post(url, json=array_data)
series_path = f"input/load/series/load_{area_id}"
rows_number = series.shape[0]
expected_rows = 8760
if rows_number < expected_rows:
raise MatrixUploadError(area_id, "load", f"Expected {expected_rows} rows and received {rows_number}.")
upload_series(self._base_url, self.study_id, self._wrapper, series, series_path)
except APIError as e:
raise MatrixUploadError(area.id, matrix_type, e.message) from e
raise MatrixUploadError(area_id, "load", e.message) from e

def create_load(self, area: Area, series: pd.DataFrame) -> None:
series_path = f"input/load/series/load_{area.id}"
rows_number = series.shape[0]
expected_rows = 8760
if rows_number < expected_rows:
raise MatrixUploadError(area.id, "load", f"Expected {expected_rows} rows and received {rows_number}.")
self._upload_series(area, series, series_path, "load")

def create_wind(self, area: Area, series: pd.DataFrame) -> None:
series_path = f"input/wind/series/wind_{area.id}"
self._upload_series(area, series, series_path, "wind")
def create_wind(self, area_id: str, series: pd.DataFrame) -> None:
try:
series_path = f"input/wind/series/wind_{area_id}"
upload_series(self._base_url, self.study_id, self._wrapper, series, series_path)
except APIError as e:
raise MatrixUploadError(area_id, "wind", e.message) from e

def create_reserves(self, area: Area, series: pd.DataFrame) -> None:
series_path = f"input/reserves/{area.id}"
self._upload_series(area, series, series_path, "reserves")
def create_reserves(self, area_id: str, series: pd.DataFrame) -> None:
try:
series_path = f"input/reserves/{area_id}"
upload_series(self._base_url, self.study_id, self._wrapper, series, series_path)
except APIError as e:
raise MatrixUploadError(area_id, "reserves", e.message) from e

def create_solar(self, area: Area, series: pd.DataFrame) -> None:
series_path = f"input/solar/series/solar_{area.id}"
self._upload_series(area, series, series_path, "solar")
def create_solar(self, area_id: str, series: pd.DataFrame) -> None:
try:
series_path = f"input/solar/series/solar_{area_id}"
upload_series(self._base_url, self.study_id, self._wrapper, series, series_path)
except APIError as e:
raise MatrixUploadError(area_id, "solar", e.message) from e

def create_misc_gen(self, area: Area, series: pd.DataFrame) -> None:
series_path = f"input/misc-gen/miscgen-{area.id}"
self._upload_series(area, series, series_path, "misc-gen")
def create_misc_gen(self, area_id: str, series: pd.DataFrame) -> None:
try:
series_path = f"input/misc-gen/miscgen-{area_id}"
upload_series(self._base_url, self.study_id, self._wrapper, series, series_path)
except APIError as e:
raise MatrixUploadError(area_id, "misc-gen", e.message) from e

def create_hydro(
self,
Expand Down Expand Up @@ -439,37 +447,33 @@ def _create_hydro_series(self, area_id: str, matrices: Dict[HydroMatrixName, pd.

self._replace_matrix_request(json_payload)

def update_area_properties(self, area: Area, properties: AreaProperties) -> AreaProperties:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/properties/form"
def update_area_properties(self, area_id: str, properties: AreaProperties) -> AreaProperties:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/properties/form"
try:
body = properties.model_dump(mode="json", exclude_none=True)
if not body:
return area.properties

self._wrapper.put(url, json=body)
response = self._wrapper.get(url)
area_properties = AreaProperties.model_validate(response.json())

except APIError as e:
raise AreaPropertiesUpdateError(area.id, e.message) from e
raise AreaPropertiesUpdateError(area_id, e.message) from e

return area_properties

def update_area_ui(self, area: Area, ui: AreaUi) -> AreaUi:
def update_area_ui(self, area_id: str, ui: AreaUi) -> AreaUi:
base_url = f"{self._base_url}/studies/{self.study_id}/areas"
try:
url = f"{base_url}/{area.id}/ui"
url = f"{base_url}/{area_id}/ui"
json_content = ui.model_dump(exclude_none=True)
if "layer" in json_content:
layer = json_content["layer"]
url += f"?layer={layer}"
del json_content["layer"]
if not json_content:
return area.ui

# Gets current UI
response = self._wrapper.get(f"{base_url}?type=AREA&ui=true")
json_ui = response.json()[area.id]
json_ui = response.json()[area_id]
ui_response = AreaUiResponse.model_validate(json_ui)
current_ui = ui_response.to_craft()
del current_ui["layer"]
Expand All @@ -479,71 +483,75 @@ def update_area_ui(self, area: Area, ui: AreaUi) -> AreaUi:

url = f"{base_url}?type=AREA&ui=true"
response = self._wrapper.get(url)
json_ui = response.json()[area.id]
json_ui = response.json()[area_id]
ui_response = AreaUiResponse.model_validate(json_ui)
area_ui = AreaUi.model_validate(ui_response.to_craft())

except APIError as e:
raise AreaUiUpdateError(area.id, e.message) from e
raise AreaUiUpdateError(area_id, e.message) from e

return area_ui

def delete_area(self, area: Area) -> None:
area_id = area.id
def delete_area(self, area_id: str) -> None:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}"
try:
self._wrapper.delete(url)
except APIError as e:
raise AreaDeletionError(area_id, e.message) from e

def delete_thermal_clusters(self, area: Area, clusters: List[ThermalCluster]) -> None:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/clusters/thermal"
def delete_thermal_clusters(self, area_id: str, clusters: List[ThermalCluster]) -> None:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/clusters/thermal"
body = [cluster.id for cluster in clusters]
try:
self._wrapper.delete(url, json=body)
except APIError as e:
raise ThermalDeletionError(area.id, body, e.message) from e
raise ThermalDeletionError(area_id, body, e.message) from e

def delete_renewable_clusters(self, area: Area, clusters: List[RenewableCluster]) -> None:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/clusters/renewable"
def delete_renewable_clusters(self, area_id: str, clusters: List[RenewableCluster]) -> None:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/clusters/renewable"
body = [cluster.id for cluster in clusters]
try:
self._wrapper.delete(url, json=body)
except APIError as e:
raise RenewableDeletionError(area.id, body, e.message) from e
raise RenewableDeletionError(area_id, body, e.message) from e

def delete_st_storages(self, area: Area, storages: List[STStorage]) -> None:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/storages"
def delete_st_storages(self, area_id: str, storages: List[STStorage]) -> None:
url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/storages"
body = [storage.id for storage in storages]
try:
self._wrapper.delete(url, json=body)
except APIError as e:
raise STStorageDeletionError(area.id, body, e.message) from e
raise STStorageDeletionError(area_id, body, e.message) from e

def get_matrix(self, area_id: str, series_path: str, matrix_type: str) -> pd.DataFrame:
def get_load_matrix(self, area_id: str) -> pd.DataFrame:
try:
raw_url = f"{self._base_url}/studies/{self.study_id}/raw?path={series_path}"
response = self._wrapper.get(raw_url)
json_df = response.json()
dataframe = pd.DataFrame(data=json_df["data"], index=json_df["index"], columns=json_df["columns"])
return dataframe
return get_matrix(self._base_url, self.study_id, self._wrapper, f"input/load/series/load_{area_id}")
except APIError as e:
raise MatrixDownloadError(area_id, matrix_type, e.message) from e

def get_load_matrix(self, area: Area) -> pd.DataFrame:
return self.get_matrix(area.id, f"input/load/series/load_{area.id}", "load")
raise MatrixDownloadError(area_id, "load", e.message)

def get_solar_matrix(self, area: Area) -> pd.DataFrame:
return self.get_matrix(area.id, f"input/solar/series/solar_{area.id}", "solar")
def get_solar_matrix(self, area_id: str) -> pd.DataFrame:
try:
return get_matrix(self._base_url, self.study_id, self._wrapper, f"input/solar/series/solar_{area_id}")
except APIError as e:
raise MatrixDownloadError(area_id, "solar", e.message)

def get_wind_matrix(self, area: Area) -> pd.DataFrame:
return self.get_matrix(area.id, f"input/wind/series/wind_{area.id}", "wind")
def get_wind_matrix(self, area_id: str) -> pd.DataFrame:
try:
return get_matrix(self._base_url, self.study_id, self._wrapper, f"input/wind/series/wind_{area_id}")
except APIError as e:
raise MatrixDownloadError(area_id, "wind", e.message)

def get_reserves_matrix(self, area: Area) -> pd.DataFrame:
return self.get_matrix(area.id, f"input/reserves/{area.id}", "reserves")
def get_reserves_matrix(self, area_id: str) -> pd.DataFrame:
try:
return get_matrix(self._base_url, self.study_id, self._wrapper, f"input/reserves/{area_id}")
except APIError as e:
raise MatrixDownloadError(area_id, "reserves", e.message)

def get_misc_gen_matrix(self, area: Area) -> pd.DataFrame:
return self.get_matrix(area.id, f"input/misc-gen/miscgen-{area.id}", "misc-gen")
def get_misc_gen_matrix(self, area_id: str) -> pd.DataFrame:
try:
return get_matrix(self._base_url, self.study_id, self._wrapper, f"input/misc-gen/miscgen-{area_id}")
except APIError as e:
raise MatrixDownloadError(area_id, "misc-gen", e.message)

def craft_ui(self, url_str: str, area_id: str) -> AreaUi:
response = self._wrapper.get(url_str)
Expand Down
2 changes: 1 addition & 1 deletion src/antares/service/api_services/binding_constraint_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def update_binding_constraint_properties(
def get_constraint_matrix(self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName) -> pd.DataFrame:
try:
path = PurePosixPath("input") / "bindingconstraints" / f"{constraint.id}_{matrix_name.value}"
return get_matrix(f"{self._base_url}/studies/{self.study_id}/raw?path={path}", self._wrapper)
return get_matrix(self._base_url, self.study_id, self._wrapper, path.as_posix())
except APIError as e:
raise ConstraintMatrixDownloadError(constraint.id, matrix_name.value, e.message) from e

Expand Down
Loading

0 comments on commit ba5854d

Please sign in to comment.