Skip to content

Commit

Permalink
fix(matrix): return default empty matrix even when called with format…
Browse files Browse the repository at this point in the history
…ted=False (#2286)
  • Loading branch information
MartinBelthle authored Jan 9, 2025
1 parent a15fdea commit 33084fd
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,7 @@ def get_file_content(self) -> OriginalFile:
else:
content = self.config.path.read_bytes()
return OriginalFile(content=content, suffix=suffix, filename=filename)

@override
def get_default_empty_matrix(self) -> t.Optional[npt.NDArray[np.float64]]:
return self.default_empty
26 changes: 22 additions & 4 deletions antarest/study/storage/rawstudy/model/filesystem/matrix/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
from pathlib import Path
from typing import List, Optional, Union, cast

import numpy as np
import pandas as pd
from numpy import typing as npt
from typing_extensions import override

from antarest.core.model import JSON
Expand Down Expand Up @@ -127,16 +129,25 @@ def load(
formatted: bool = True,
) -> Union[bytes, JSON]:
file_path, tmp_dir = self._get_real_file_path()
if not formatted:
if file_path.exists():
return file_path.read_bytes()

if formatted:
return self.parse_as_json(file_path)

if not file_path.exists():
logger.warning(f"Missing file {self.config.path}")
if tmp_dir:
tmp_dir.cleanup()
return b""

return self.parse_as_json(file_path)
file_content = file_path.read_bytes()
if file_content != b"":
return file_content

# If the content is empty, we should return the default matrix to do the same as `parse_as_json()`
default_matrix = self.get_default_empty_matrix()
if default_matrix is None:
return b""
return default_matrix.tobytes()

@abstractmethod
def parse_as_json(self, file_path: Optional[Path] = None) -> JSON:
Expand All @@ -145,6 +156,13 @@ def parse_as_json(self, file_path: Optional[Path] = None) -> JSON:
"""
raise NotImplementedError()

@abstractmethod
def get_default_empty_matrix(self) -> Optional[npt.NDArray[np.float64]]:
"""
Returns the default matrix to return when the existing one is empty
"""
raise NotImplementedError()

@override
def dump(
self,
Expand Down
97 changes: 37 additions & 60 deletions tests/storage/integration/test_STA_mini.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from typing import Union
from unittest.mock import Mock

import numpy as np
import pytest
from fastapi import FastAPI
from starlette.testclient import TestClient
Expand Down Expand Up @@ -172,44 +173,35 @@ def test_sta_mini_study_antares(storage_service, url: str, expected_output: str)

@pytest.mark.integration_test
@pytest.mark.parametrize(
"url, expected_output",
"url, expected_output, formatted",
[
(
f"/v1/studies/{UUID}/raw?path=input/bindingconstraints/bindingconstraints",
{},
),
(f"/v1/studies/{UUID}/raw?path=input/bindingconstraints/bindingconstraints", {}, True),
(
f"/v1/studies/{UUID}/raw?path=input/hydro/series/de/mod",
{
"columns": [0, 1, 2],
"index": list(range(365)),
"data": [[0.0]] * 365,
},
True,
),
(
f"/v1/studies/{UUID}/raw?path=input/areas/list",
["DE", "ES", "FR", "IT"],
),
(
f"/v1/studies/{UUID}/raw?path=input/areas/sets/all areas/output",
False,
),
(f"/v1/studies/{UUID}/raw?path=input/areas/list", ["DE", "ES", "FR", "IT"], True),
(f"/v1/studies/{UUID}/raw?path=input/areas/sets/all areas/output", False, True),
(
f"/v1/studies/{UUID}/raw?path=input/areas/de/optimization/nodal optimization/spread-spilled-energy-cost",
0,
True,
),
(f"/v1/studies/{UUID}/raw?path=input/areas/de/ui/layerX/0", 1),
(
f"/v1/studies/{UUID}/raw?path=input/hydro/allocation/de/[allocation]/de",
1,
),
(f"/v1/studies/{UUID}/raw?path=input/areas/de/ui/layerX/0", 1, True),
(f"/v1/studies/{UUID}/raw?path=input/hydro/allocation/de/[allocation]/de", 1, True),
(
f"/v1/studies/{UUID}/raw?path=input/hydro/common/capacity/reservoir_fr",
{
"columns": [0, 1, 2],
"index": list(range(365)),
"data": [[0, 0.5, 1]] * 365,
},
True,
),
(
f"/v1/studies/{UUID}/raw?path=input/thermal/series/fr/05_nuclear/series",
Expand All @@ -218,47 +210,29 @@ def test_sta_mini_study_antares(storage_service, url: str, expected_output: str)
"index": list(range(8760)),
"data": [[2000]] * 8760,
},
True,
),
(
f"/v1/studies/{UUID}/raw?path=input/hydro/prepro/correlation/general/mode",
"annual",
),
(
f"/v1/studies/{UUID}/raw?path=input/hydro/prepro/fr/prepro/prepro/intermonthly-correlation",
0.5,
),
(f"/v1/studies/{UUID}/raw?path=input/hydro/prepro/correlation/general/mode", "annual", True),
(f"/v1/studies/{UUID}/raw?path=input/hydro/prepro/fr/prepro/prepro/intermonthly-correlation", 0.5, True),
(
f"/v1/studies/{UUID}/raw?path=input/hydro/prepro/fr/energy",
{"data": [[]], "index": [0], "columns": []},
),
(
f"/v1/studies/{UUID}/raw?path=input/hydro/hydro/inter-monthly-breakdown/fr",
1,
),
(
f"/v1/studies/{UUID}/raw?path=input/thermal/areas/unserverdenergycost/de",
3000.0,
),
(
f"/v1/studies/{UUID}/raw?path=input/thermal/clusters/fr/list/05_nuclear/marginal-cost",
50,
),
(
f"/v1/studies/{UUID}/raw?path=input/links/fr/properties/it/hurdles-cost",
True,
),
(f"/v1/studies/{UUID}/raw?path=input/hydro/hydro/inter-monthly-breakdown/fr", 1, True),
(f"/v1/studies/{UUID}/raw?path=input/thermal/areas/unserverdenergycost/de", 3000.0, True),
(f"/v1/studies/{UUID}/raw?path=input/thermal/clusters/fr/list/05_nuclear/marginal-cost", 50, True),
(f"/v1/studies/{UUID}/raw?path=input/links/fr/properties/it/hurdles-cost", True, True),
(
f"/v1/studies/{UUID}/raw?path=input/links/fr/it",
{
"columns": list(range(8)),
"index": list(range(8760)),
"data": [[100000, 100000, 0.01, 0.01, 0, 0, 0, 0]] * 8760,
},
True,
),
(
f"/v1/studies/{UUID}/raw?path=input/load/prepro/fr/k",
{"data": [[]], "index": [0], "columns": []},
),
(f"/v1/studies/{UUID}/raw?path=input/load/prepro/fr/k", {"data": [[]], "index": [0], "columns": []}, True),
(
f"/v1/studies/{UUID}/raw?path=input/load/series",
{
Expand All @@ -267,6 +241,7 @@ def test_sta_mini_study_antares(storage_service, url: str, expected_output: str)
"load_fr": "matrixfile://load_fr.txt",
"load_it": "matrixfile://load_it.txt",
},
True,
),
(
f"/v1/studies/{UUID}/raw?path=input/load/series/load_fr",
Expand All @@ -275,14 +250,23 @@ def test_sta_mini_study_antares(storage_service, url: str, expected_output: str)
"index": list(range(8760)),
"data": [[i % 168 * 100] for i in range(8760)],
},
True,
),
(
pytest.param(
f"/v1/studies/{UUID}/raw?path=input/misc-gen/miscgen-fr",
{
"columns": [0, 1, 2, 3, 4, 5, 6, 7],
"index": list(range(8760)),
"data": [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]] * 8760,
},
True,
id="empty_matrix_formatted",
),
pytest.param(
f"/v1/studies/{UUID}/raw?path=input/misc-gen/miscgen-fr",
np.array([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]] * 8760).tobytes(),
False,
id="empty_matrix_unformatted",
),
(
f"/v1/studies/{UUID}/raw?path=input/reserves/fr",
Expand All @@ -291,39 +275,32 @@ def test_sta_mini_study_antares(storage_service, url: str, expected_output: str)
"index": list(range(8760)),
"data": [[0.0]] * 8760,
},
True,
),
(
f"/v1/studies/{UUID}/raw?path=input/solar/prepro/fr/k",
{"data": [[]], "index": [0], "columns": []},
),
(f"/v1/studies/{UUID}/raw?path=input/solar/prepro/fr/k", {"data": [[]], "index": [0], "columns": []}, True),
(
f"/v1/studies/{UUID}/raw?path=input/solar/series/solar_fr",
{
"columns": [0],
"index": list(range(8760)),
"data": [[0.0]] * 8760,
},
True,
),
(
f"/v1/studies/{UUID}/raw?path=input/wind/prepro/fr/k",
{"data": [[]], "index": [0], "columns": []},
),
(f"/v1/studies/{UUID}/raw?path=input/wind/prepro/fr/k", {"data": [[]], "index": [0], "columns": []}, True),
(
f"/v1/studies/{UUID}/raw?path=input/wind/series/wind_fr",
{
"columns": [0],
"index": list(range(8760)),
"data": [[0.0]] * 8760,
},
True,
),
],
)
def test_sta_mini_input(storage_service, url: str, expected_output: dict):
assert_with_errors(
storage_service=storage_service,
url=url,
expected_output=expected_output,
)
def test_sta_mini_input(storage_service, url: str, expected_output: dict, formatted: bool):
assert_with_errors(storage_service=storage_service, url=url, expected_output=expected_output, formatted=formatted)


@pytest.mark.integration_test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
from typing import List, Optional
from unittest.mock import Mock

import numpy as np
import pandas as pd # type: ignore
from numpy import typing as npt

from antarest.core.model import JSON
from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig
Expand All @@ -41,6 +43,9 @@ def __init__(self, context: ContextServer, config: FileStudyTreeConfig) -> None:
def parse_as_json(self, file_path: Optional[Path] = None) -> JSON:
return MOCK_MATRIX_JSON

def get_default_empty_matrix(self) -> Optional[npt.NDArray[np.float64]]:
pass

def check_errors(self, data: str, url: Optional[List[str]] = None, raising: bool = False) -> List[str]:
pass # not used

Expand Down

0 comments on commit 33084fd

Please sign in to comment.