Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM python:3.11-slim-bullseye

# RUN apt update && apt install -y procps gdb
RUN apt update && apt install -y procps gdb gcc g++ make git

# Add the `ls` alias to simplify debugging
RUN echo "alias ll='/bin/ls -l --color=auto'" >> /root/.bashrc
Expand All @@ -18,4 +18,4 @@ COPY ./alembic.ini /alembic.ini

RUN pip3 install --no-cache-dir --upgrade pip && pip3 install --no-cache-dir -r /conf/requirements.txt

ENTRYPOINT ["./scripts/start.sh"]
ENTRYPOINT ["./scripts/start.sh"]
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class AdvancedParameters(AntaresBaseModel):
initial_reservoir_levels: Optional[InitialReservoirLevel] = None
# Field introduced in v9.3
accurate_shave_peaks_include_short_term_storage: Optional[bool] = None
hydro_rule_curves: Optional[str] = None


class AdvancedParametersUpdate(AntaresBaseModel):
Expand Down Expand Up @@ -145,6 +146,7 @@ class AdvancedParametersUpdate(AntaresBaseModel):
seed_initial_reservoir_levels: Optional[int] = None
initial_reservoir_levels: Optional[InitialReservoirLevel] = None
accurate_shave_peaks_include_short_term_storage: Optional[bool] = None
hydro_rule_curves: Optional[str] = None


def update_advanced_parameters(
Expand Down
27 changes: 25 additions & 2 deletions antarest/study/storage/matrix_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
import pandas as pd
from antares.study.version import StudyVersion

from antarest.study.model import STUDY_VERSION_8_2, STUDY_VERSION_8_6, STUDY_VERSION_8_7
from antarest.study.model import (
STUDY_VERSION_8_2,
STUDY_VERSION_8_6,
STUDY_VERSION_8_7,
STUDY_VERSION_9_2,
STUDY_VERSION_9_3,
)
from antarest.study.storage.utils import MONTHS


Expand Down Expand Up @@ -177,6 +183,19 @@ def _process_links_columns(self, matrix_path: str) -> Sequence[str]:
# Scenarized RHS for binding constraints
_SPECIFIC_MATRICES_8_7["input/bindingconstraints/*"] = _MatrixProfile(cols=[], rows=[])

_SPECIFIC_MATRICES_9_2 = copy.deepcopy(_SPECIFIC_MATRICES_8_7)

_SPECIFIC_MATRICES_9_2["input/hydro/series/*/maxHourlyGenPower"] = _MatrixProfile(cols=[], rows=[])
_SPECIFIC_MATRICES_9_2["input/hydro/series/*/maxHourlyPumpPower"] = _MatrixProfile(cols=[], rows=[])
_SPECIFIC_MATRICES_9_2["input/hydro/common/capacity/maxDailyGenEnergy_*"] = _MatrixProfile(cols=[], rows=[])
_SPECIFIC_MATRICES_9_2["input/hydro/common/capacity/maxDailyPumpEnergy_*"] = _MatrixProfile(cols=[], rows=[])

_SPECIFIC_MATRICES_9_3 = copy.deepcopy(_SPECIFIC_MATRICES_9_2)

_SPECIFIC_MATRICES_9_3["input/hydro/series/*/maxDailyReservoirLevels"] = _MatrixProfile(cols=[], rows=[])
_SPECIFIC_MATRICES_9_3["input/hydro/series/*/minDailyReservoirLevels"] = _MatrixProfile(cols=[], rows=[])
_SPECIFIC_MATRICES_9_3["input/hydro/series/*/avgDailyReservoirLevels"] = _MatrixProfile(cols=[], rows=[])


def adjust_matrix_columns_index(
df: pd.DataFrame, matrix_path: str, with_index: bool, with_header: bool, study_version: StudyVersion
Expand All @@ -200,8 +219,12 @@ def adjust_matrix_columns_index(
matrix_profiles = _SPECIFIC_MATRICES_8_2
elif study_version < STUDY_VERSION_8_7:
matrix_profiles = _SPECIFIC_MATRICES_8_6
else:
elif study_version < STUDY_VERSION_9_2:
matrix_profiles = _SPECIFIC_MATRICES_8_7
elif study_version < STUDY_VERSION_9_3:
matrix_profiles = _SPECIFIC_MATRICES_9_2
else:
matrix_profiles = _SPECIFIC_MATRICES_9_3

# Apply the matrix profile to the dataframe to adjust the column names and index
for pattern, matrix_profile in matrix_profiles.items():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
)


class CompatibilitySection(AntaresBaseModel):
model_config = ConfigDict(extra="ignore", populate_by_name=True, alias_generator=to_kebab_case)
hydro_rule_curves: str | None = None


class AdvancedParametersSection(AntaresBaseModel):
model_config = ConfigDict(extra="ignore", populate_by_name=True, alias_generator=to_kebab_case)

Expand Down Expand Up @@ -76,6 +81,7 @@ class AdvancedParametersFileData(AntaresBaseModel):
other_preferences: OtherPreferencesSection | None = Field(default=None, alias="other preferences")
seed_parameters: SeedParametersSection | None = Field(default=None, alias="seeds - Mersenne Twister")
advanced_parameters: AdvancedParametersSection | None = Field(default=None, alias="advanced parameters")
compatibility: CompatibilitySection | None = Field(default=None, alias="compatibility")

def to_model(self) -> AdvancedParameters:
args = {}
Expand All @@ -85,6 +91,8 @@ def to_model(self) -> AdvancedParameters:
args.update(self.seed_parameters.model_dump(exclude_none=True))
if self.advanced_parameters:
args.update(self.advanced_parameters.model_dump(exclude_none=True))
if self.compatibility:
args.update(self.compatibility.model_dump(exclude_none=True))
return AdvancedParameters.model_validate(args)

@classmethod
Expand All @@ -93,6 +101,7 @@ def from_model(cls, parameters: AdvancedParameters) -> "AdvancedParametersFileDa
args["other_preferences"] = parameters.model_dump(include=set(OtherPreferencesSection.model_fields))
args["seed_parameters"] = parameters.model_dump(include=set(SeedParametersSection.model_fields))
args["advanced_parameters"] = parameters.model_dump(include=set(AdvancedParametersSection.model_fields))
args["compatibility"] = parameters.model_dump(include=set(CompatibilitySection.model_fields))
return cls.model_validate(args)


Expand All @@ -101,6 +110,7 @@ def parse_advanced_parameters(version: StudyVersion, data: dict[str, Any]) -> Ad
args["advanced_parameters"] = data.get("advanced parameters", {})
args["other_preferences"] = data.get("other preferences", {})
args["seed_parameters"] = data.get("seeds - Mersenne Twister", {})
args["compatibility"] = data.get("compatibility", {})
parameters = AdvancedParametersFileData.model_validate(args).to_model()
validate_advanced_parameters_against_version(version, parameters)
initialize_advanced_parameters_against_version(parameters, version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
from typing_extensions import override

from antarest.core.serde.np_array import NpArray
from antarest.study.model import STUDY_VERSION_6_5
from antarest.study.model import STUDY_VERSION_6_5, STUDY_VERSION_9_2
from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode
from antarest.study.storage.rawstudy.model.filesystem.inode import TREE
from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import default_scenario_daily_ones
from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import (
default_scenario_daily,
default_scenario_daily_ones,
)
from antarest.study.storage.rawstudy.model.filesystem.matrix.input_series_matrix import InputSeriesMatrix
from antarest.study.storage.rawstudy.model.filesystem.matrix.matrix import MatrixFrequency

Expand Down Expand Up @@ -81,6 +84,18 @@ class MatrixInfo(TypedDict, total=False):
"start_version": STUDY_VERSION_6_5,
"default_empty": default_water_values,
},
{
"name": "maxDailyPumpEnergy",
"freq": MatrixFrequency.DAILY,
"start_version": STUDY_VERSION_9_2,
"default_empty": default_scenario_daily,
},
{
"name": "maxDailyGenEnergy",
"freq": MatrixFrequency.DAILY,
"start_version": STUDY_VERSION_9_2,
"default_empty": default_scenario_daily,
},
]


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from typing_extensions import override

from antarest.study.model import STUDY_VERSION_6_5, STUDY_VERSION_8_6
from antarest.study.model import STUDY_VERSION_6_5, STUDY_VERSION_8_6, STUDY_VERSION_9_2, STUDY_VERSION_9_3
from antarest.study.storage.rawstudy.model.filesystem.folder_node import FolderNode
from antarest.study.storage.rawstudy.model.filesystem.inode import TREE, INode
from antarest.study.storage.rawstudy.model.filesystem.matrix.constants import (
Expand Down Expand Up @@ -54,4 +54,37 @@ def build(self) -> TREE:
freq=MatrixFrequency.HOURLY,
default_empty=default_scenario_hourly,
)

if study_version >= STUDY_VERSION_9_2:
hydro_series_matrices["maxHourlyGenPower"] = InputSeriesMatrix(
self.matrix_mapper,
self.config.next_file("maxHourlyGenPower.txt"),
freq=MatrixFrequency.HOURLY,
default_empty=default_scenario_hourly,
)
hydro_series_matrices["maxHourlyPumpPower"] = InputSeriesMatrix(
self.matrix_mapper,
self.config.next_file("maxHourlyPumpPower.txt"),
freq=MatrixFrequency.HOURLY,
default_empty=default_scenario_hourly,
)
if study_version >= STUDY_VERSION_9_3:
hydro_series_matrices["maxDailyReservoirLevels"] = InputSeriesMatrix(
self.matrix_mapper,
self.config.next_file("maxDailyReservoirLevels.txt"),
freq=MatrixFrequency.DAILY,
default_empty=default_scenario_daily,
)
hydro_series_matrices["minDailyReservoirLevels"] = InputSeriesMatrix(
self.matrix_mapper,
self.config.next_file("minDailyReservoirLevels.txt"),
freq=MatrixFrequency.DAILY,
default_empty=default_scenario_daily,
)
hydro_series_matrices["avgDailyReservoirLevels"] = InputSeriesMatrix(
self.matrix_mapper,
self.config.next_file("avgDailyReservoirLevels.txt"),
freq=MatrixFrequency.DAILY,
default_empty=default_scenario_daily,
)
return hydro_series_matrices
26 changes: 23 additions & 3 deletions antarest/study/storage/rawstudy/raw_study_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@
from antarest.core.serde.ini_reader import read_ini
from antarest.core.utils.archives import ArchiveFormat, extract_archive
from antarest.matrixstore.matrix_uri_mapper import NormalizedMatrixUriMapper
from antarest.study.model import DEFAULT_WORKSPACE_NAME, STUDY_VERSION_9_2, RawStudy, Study, StudyAdditionalData
from antarest.study.model import (
DEFAULT_WORKSPACE_NAME,
STUDY_VERSION_9_2,
STUDY_VERSION_9_3,
RawStudy,
Study,
StudyAdditionalData,
)
from antarest.study.repository import StudyMetadataRepository
from antarest.study.storage.abstract_storage_service import AbstractStorageService
from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig, FileStudyTreeConfigDTO
Expand Down Expand Up @@ -546,5 +553,18 @@ def checks_antares_web_compatibility(study: Study) -> None:
# The section is optional and AntaresWeb supports the default Simulator value
if "compatibility" in ini_content and "hydro-pmax" in ini_content["compatibility"]:
hydro_pmax_value = ini_content["compatibility"]["hydro-pmax"]
if hydro_pmax_value == "hourly":
raise NotImplementedError("AntaresWeb doesn't support the value 'hourly' for the flag 'hydro-pmax'")
if hydro_pmax_value != "hourly" and hydro_pmax_value != "daily":
raise NotImplementedError(
f"AntaresWeb doesn't support the value {hydro_pmax_value} for the flag 'hydro-pmax'"
)

if StudyVersion.parse(study.version) >= STUDY_VERSION_9_3:
general_data_path = Path(study.path) / "settings" / "generaldata.ini"
ini_content = read_ini(general_data_path)
# The section is optional and AntaresWeb supports the default Simulator value
if "compatibility" in ini_content and "hydro-rule-curves" in ini_content["compatibility"]:
hydro_rule_curves_value = ini_content["compatibility"]["hydro-rule-curves"]
if hydro_rule_curves_value != "single" and hydro_rule_curves_value != "scenarized":
raise NotImplementedError(
f"AntaresWeb doesn't support the value {hydro_rule_curves_value} for the flag 'hydro-rule-curves'"
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@
NULL_SCENARIO_MATRIX = pd.DataFrame([[0.0]] * 8760)
FIXED_4_COLUMNS = pd.DataFrame([[0.0, 0.0, 0.0, 0.0]] * 8760)
FIXED_8_COLUMNS = pd.DataFrame([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]] * 8760)
DAILY_ROWS_OF_24S = pd.DataFrame([[24.0]] * 365)
DAILY_ROWS_OF_ZEROS = pd.DataFrame([[0.0]] * 365)
DAILY_ROWS_OF_HALFS = pd.DataFrame([[0.5]] * 365)
DAILY_ROWS_OF_ONES = pd.DataFrame([[1.0]] * 365)
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
from antarest.study.model import STUDY_VERSION_6_5, STUDY_VERSION_8_2
from antarest.study.storage.variantstudy.business import matrix_constants
from antarest.study.storage.variantstudy.business.matrix_constants.common import (
DAILY_ROWS_OF_24S,
DAILY_ROWS_OF_HALFS,
DAILY_ROWS_OF_ONES,
DAILY_ROWS_OF_ZEROS,
FIXED_4_COLUMNS,
FIXED_8_COLUMNS,
NULL_MATRIX,
Expand Down Expand Up @@ -51,6 +55,13 @@
NULL_MATRIX_NAME = "null_matrix"
EMPTY_SCENARIO_MATRIX = "empty_scenario_matrix"
ONES_SCENARIO_MATRIX = "ones_scenario_matrix"
HYDRO_MAX_HOURLY_GEN_POWER = "max_hourly_gen_power"
HYDRO_MAX_HOURLY_PUMP_POWER = "max_hourly_pump_power"
HYDRO_MAX_DAILY_GEN_ENERGY = "max_daily_gen_energy"
HYDRO_MAX_DAILY_PUMP_ENERGY = "max_daily_pump_energy"
HYDRO_MAX_DAILY_RESERVOIR_LEVELS = "max_daily_reservoir_levels"
HYDRO_MIN_DAILY_RESERVOIR_LEVELS = "min_daily_reservoir_levels"
HYDRO_AVG_DAILY_RESERVOIR_LEVELS = "avg_daily_reservoir_levels"

# Binding constraint aliases
BINDING_CONSTRAINT_HOURLY_v86 = "empty_2nd_member_hourly_v86"
Expand Down Expand Up @@ -112,6 +123,13 @@ def init_constant_matrices(
self.hashes[EMPTY_SCENARIO_MATRIX] = self.matrix_service.create(NULL_SCENARIO_MATRIX)
self.hashes[RESERVES_TS] = self.matrix_service.create(FIXED_4_COLUMNS)
self.hashes[MISCGEN_TS] = self.matrix_service.create(FIXED_8_COLUMNS)
self.hashes[HYDRO_MAX_HOURLY_GEN_POWER] = self.matrix_service.create(NULL_MATRIX)
self.hashes[HYDRO_MAX_HOURLY_PUMP_POWER] = self.matrix_service.create(NULL_MATRIX)
self.hashes[HYDRO_MAX_DAILY_GEN_ENERGY] = self.matrix_service.create(DAILY_ROWS_OF_24S)
self.hashes[HYDRO_MAX_DAILY_PUMP_ENERGY] = self.matrix_service.create(DAILY_ROWS_OF_24S)
self.hashes[HYDRO_MAX_DAILY_RESERVOIR_LEVELS] = self.matrix_service.create(DAILY_ROWS_OF_ONES)
self.hashes[HYDRO_MIN_DAILY_RESERVOIR_LEVELS] = self.matrix_service.create(DAILY_ROWS_OF_ZEROS)
self.hashes[HYDRO_AVG_DAILY_RESERVOIR_LEVELS] = self.matrix_service.create(DAILY_ROWS_OF_HALFS)

# Binding constraint matrices
series_before_87 = matrix_constants.binding_constraint.series_before_v87
Expand Down Expand Up @@ -222,3 +240,24 @@ def get_st_storage_upper_rule_curve(self) -> str:
def get_st_storage_inflows(self) -> str:
"""2D-matrix of shape (8760, 1), filled-in with zeros."""
return MATRIX_PROTOCOL_PREFIX + self.hashes[ST_STORAGE_INFLOWS]

def get_hydro_max_hourly_gen_power(self) -> str:
return MATRIX_PROTOCOL_PREFIX + self.hashes[HYDRO_MAX_HOURLY_GEN_POWER]

def get_hydro_max_hourly_pump_power(self) -> str:
return MATRIX_PROTOCOL_PREFIX + self.hashes[HYDRO_MAX_HOURLY_PUMP_POWER]

def get_max_daily_gen_energy(self) -> str:
return MATRIX_PROTOCOL_PREFIX + self.hashes[HYDRO_MAX_DAILY_GEN_ENERGY]

def get_max_daily_pump_energy(self) -> str:
return MATRIX_PROTOCOL_PREFIX + self.hashes[HYDRO_MAX_DAILY_PUMP_ENERGY]

def get_min_reservoir_level(self) -> str:
return MATRIX_PROTOCOL_PREFIX + self.hashes[HYDRO_MIN_DAILY_RESERVOIR_LEVELS]

def get_max_reservoir_level(self) -> str:
return MATRIX_PROTOCOL_PREFIX + self.hashes[HYDRO_MAX_DAILY_RESERVOIR_LEVELS]

def get_avg_reservoir_level(self) -> str:
return MATRIX_PROTOCOL_PREFIX + self.hashes[HYDRO_AVG_DAILY_RESERVOIR_LEVELS]
37 changes: 36 additions & 1 deletion antarest/study/storage/variantstudy/model/command/create_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@
from typing_extensions import override

from antarest.core.model import JSON
from antarest.study.model import STUDY_VERSION_6_5, STUDY_VERSION_8_1, STUDY_VERSION_8_3, STUDY_VERSION_8_6
from antarest.study.model import (
STUDY_VERSION_6_5,
STUDY_VERSION_8_1,
STUDY_VERSION_8_3,
STUDY_VERSION_8_6,
STUDY_VERSION_9_2,
STUDY_VERSION_9_3,
)
from antarest.study.storage.rawstudy.model.filesystem.config.identifier import transform_name_to_id
from antarest.study.storage.rawstudy.model.filesystem.config.model import Area, EnrModelling
from antarest.study.storage.rawstudy.model.filesystem.factory import FileStudy
Expand Down Expand Up @@ -261,6 +268,34 @@ def _apply(self, study_data: FileStudy, listener: Optional[ICommandListener] = N
new_area_data["input"]["st-storage"] = {"clusters": {area_id: {"list": {}}}}
new_area_data["input"]["hydro"]["series"][area_id]["mingen"] = null_matrix

if version >= STUDY_VERSION_9_2:
maxHourlyGenPower = self.command_context.generator_matrix_constants.get_hydro_max_hourly_gen_power()
maxHourlyPumpPower = self.command_context.generator_matrix_constants.get_hydro_max_hourly_pump_power()

new_area_data["input"]["hydro"]["series"][area_id]["maxHourlyGenPower"] = maxHourlyGenPower

new_area_data["input"]["hydro"]["series"][area_id]["maxHourlyPumpPower"] = maxHourlyPumpPower

new_area_data["input"]["hydro"]["common"]["capacity"][f"maxDailyGenEnergy_{area_id}"] = (
self.command_context.generator_matrix_constants.get_max_daily_gen_energy()
)

new_area_data["input"]["hydro"]["common"]["capacity"][f"maxDailyPumpEnergy_{area_id}"] = (
self.command_context.generator_matrix_constants.get_max_daily_pump_energy()
)
if version >= STUDY_VERSION_9_3:
new_area_data["input"]["hydro"]["series"][area_id]["maxDailyReservoirLevels"] = (
self.command_context.generator_matrix_constants.get_max_reservoir_level()
)

new_area_data["input"]["hydro"]["series"][area_id]["minDailyReservoirLevels"] = (
self.command_context.generator_matrix_constants.get_min_reservoir_level()
)

new_area_data["input"]["hydro"]["series"][area_id]["avgDailyReservoirLevels"] = (
self.command_context.generator_matrix_constants.get_avg_reservoir_level()
)

new_area_data["input"]["hydro"]["hydro"] = hydro_config

# NOTE regarding the following configurations:
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Antares-Launcher==1.4.5
antares-study-version==1.0.20
#antares-study-version==1.0.20
git+https://github.com/rte-i/antares-study-version-rtei.git@change-request24#egg=antares-study-version
antares-timeseries-generation==0.1.7

# When you install `fastapi[all]`, you get FastAPI along with additional dependencies:
Expand Down
2 changes: 1 addition & 1 deletion resources/antares-desktop-fs/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ server:
worker_threadpool_size: 12

logging:
logfile: ./logs/antarest.log
logfile: ./logs/antarest.log
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def test_set_advanced_parameters_values(
"seedUnsuppliedEnergyCosts": 6005489,
"sheddingPolicy": "shave peaks",
"unitCommitmentMode": "fast",
"hydroRuleCurves": None,
}

if study_version:
Expand Down
Loading
Loading