Skip to content

Commit

Permalink
feat(local): add Thermal reading (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
killian-scalian authored Dec 9, 2024
1 parent a8ef8e5 commit e6ccad4
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 3 deletions.
82 changes: 79 additions & 3 deletions src/antares/service/local_services/thermal_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@
import pandas as pd

from antares.config.local_configuration import LocalConfiguration
from antares.model.thermal import ThermalCluster, ThermalClusterMatrixName, ThermalClusterProperties
from antares.model.thermal import (
ThermalCluster,
ThermalClusterMatrixName,
ThermalClusterProperties,
ThermalClusterPropertiesLocal,
)
from antares.service.base_services import BaseThermalService
from antares.tools.ini_tool import IniFile, IniFileTypes
from antares.tools.matrix_tool import read_timeseries
from antares.tools.time_series_tool import TimeSeriesFileType


class ThermalLocalService(BaseThermalService):
Expand All @@ -31,7 +39,75 @@ def update_thermal_properties(
raise NotImplementedError

def get_thermal_matrix(self, thermal_cluster: ThermalCluster, ts_name: ThermalClusterMatrixName) -> pd.DataFrame:
raise NotImplementedError
if ts_name.value == "series":
time_serie_type = TimeSeriesFileType.THERMAL_SERIES
elif ts_name.value == "modulation":
time_serie_type = TimeSeriesFileType.THERMAL_MODULATION
elif ts_name.value == "data":
time_serie_type = TimeSeriesFileType.THERMAL_DATA
elif ts_name.value == "CO2Cost":
time_serie_type = TimeSeriesFileType.THERMAL_CO2
else:
time_serie_type = TimeSeriesFileType.THERMAL_FUEL

return read_timeseries(
time_serie_type,
self.config.study_path,
area_id=thermal_cluster.area_id,
cluster_id=thermal_cluster.properties.group.value,
)

def read_thermal_clusters(self, area_id: str) -> List[ThermalCluster]:
raise NotImplementedError
thermal_dict = IniFile(self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id).ini_dict
thermal_clusters = []
if thermal_dict:
for thermal_cluster in thermal_dict:
# TODO refactor this as it is really not clean
thermal_properties = ThermalClusterPropertiesLocal(
group=thermal_dict[thermal_cluster]["group"],
thermal_name=thermal_dict[thermal_cluster]["name"],
enabled=thermal_dict[thermal_cluster]["enabled"],
unit_count=thermal_dict[thermal_cluster]["unitcount"],
nominal_capacity=thermal_dict[thermal_cluster]["nominalcapacity"],
gen_ts=thermal_dict[thermal_cluster]["gen-ts"],
min_stable_power=thermal_dict[thermal_cluster]["min-stable-power"],
min_up_time=thermal_dict[thermal_cluster]["min-up-time"],
min_down_time=thermal_dict[thermal_cluster]["min-down-time"],
must_run=thermal_dict[thermal_cluster]["must-run"],
spinning=thermal_dict[thermal_cluster]["spinning"],
volatility_forced=thermal_dict[thermal_cluster]["volatility.forced"],
volatility_planned=thermal_dict[thermal_cluster]["volatility.planned"],
law_forced=thermal_dict[thermal_cluster]["law.forced"],
law_planned=thermal_dict[thermal_cluster]["law.planned"],
marginal_cost=thermal_dict[thermal_cluster]["marginal-cost"],
spread_cost=thermal_dict[thermal_cluster]["spread-cost"],
fixed_cost=thermal_dict[thermal_cluster]["fixed-cost"],
startup_cost=thermal_dict[thermal_cluster]["startup-cost"],
market_bid_cost=thermal_dict[thermal_cluster]["market-bid-cost"],
co2=thermal_dict[thermal_cluster]["co2"],
nh3=thermal_dict[thermal_cluster]["nh3"],
so2=thermal_dict[thermal_cluster]["so2"],
nox=thermal_dict[thermal_cluster]["nox"],
pm2_5=thermal_dict[thermal_cluster]["pm2_5"],
pm5=thermal_dict[thermal_cluster]["pm5"],
pm10=thermal_dict[thermal_cluster]["pm10"],
nmvoc=thermal_dict[thermal_cluster]["nmvoc"],
op1=thermal_dict[thermal_cluster]["op1"],
op2=thermal_dict[thermal_cluster]["op2"],
op3=thermal_dict[thermal_cluster]["op3"],
op4=thermal_dict[thermal_cluster]["op4"],
op5=thermal_dict[thermal_cluster]["op5"],
cost_generation=thermal_dict[thermal_cluster]["costgeneration"],
efficiency=thermal_dict[thermal_cluster]["efficiency"],
variable_o_m_cost=thermal_dict[thermal_cluster]["variableomcost"],
)

thermal_clusters.append(
ThermalCluster(
thermal_service=self,
area_id=area_id,
name=thermal_dict[thermal_cluster]["name"],
properties=thermal_properties.yield_thermal_cluster_properties(),
)
)
return thermal_clusters
5 changes: 5 additions & 0 deletions src/antares/tools/time_series_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class TimeSeriesFileType(Enum):
WIND_K = "input/wind/prepro/{area_id}/k.txt"
WIND_TRANSLATION = "input/wind/prepro/{area_id}/translation.txt"
RENEWABLE_DATA_SERIES = "input/renewables/series/{area_id}/{cluster_id}/series.txt"
THERMAL_SERIES = "input/thermal/series/{area_id}/{cluster_id}/series.txt"
THERMAL_DATA = "input/thermal/prepro/{area_id}/{cluster_id}/data.txt"
THERMAL_MODULATION = "input/thermal/prepro/{area_id}/{cluster_id}/modulation.txt"
THERMAL_CO2 = "input/thermal/series/{area_id}/{cluster_id}/C02Cost.txt"
THERMAL_FUEL = "input/thermal/series/{area_id}/{cluster_id}/fuelCost.txt"


class TimeSeries:
Expand Down
68 changes: 68 additions & 0 deletions tests/antares/services/local_services/test_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -1306,3 +1306,71 @@ def test_read_misc_gen_local(self, local_study_w_areas):
_write_file(file_path, expected_time_serie)
matrix = area.get_misc_gen_matrix()
pd.testing.assert_frame_equal(matrix, expected_time_serie)


class TestReadThermal:
def test_read_thermals_local(self, local_study_w_thermal):
study_path = local_study_w_thermal.service.config.study_path
local_study_object = read_study_local(study_path)
areas = local_study_object.read_areas()

for area in areas:
expected_time_serie = pd.DataFrame(
[
[-9999999980506447872, 0, 9999999980506447872],
[0, area.id, 0],
],
dtype="object",
)

thermals_list = area.read_thermal_clusters(area.id)

if thermals_list:
assert area.id == "fr"
assert isinstance(thermals_list, list)
assert isinstance(thermals_list[0], ThermalCluster)

for thermal in thermals_list:
assert thermal.name == "test thermal cluster"
assert thermal.properties.group.value == "Other 1"
assert thermal.properties.unit_count == 1
assert thermal.properties.efficiency == 100.000000
assert thermal.properties.nominal_capacity == 0.000000
assert thermal.properties.enabled
assert thermal.properties.cost_generation.value == "SetManually"

# Create folder and file for timeserie.
cluster_path = (
study_path / "input" / "thermal" / "series" / Path(area.id) / Path(thermal.properties.group.value)
)
series_path = cluster_path / "series.txt"
os.makedirs(cluster_path, exist_ok=True)
_write_file(series_path, expected_time_serie)

co2_cost_path = cluster_path / "C02Cost.txt"
_write_file(co2_cost_path, expected_time_serie)

fuelCost_path = cluster_path / "fuelCost.txt"
_write_file(fuelCost_path, expected_time_serie)

cluster_path = (
study_path / "input" / "thermal" / "prepro" / Path(area.id) / Path(thermal.properties.group.value)
)
os.makedirs(cluster_path, exist_ok=True)
series_path_1 = cluster_path / "data.txt"
series_path_2 = cluster_path / "modulation.txt"
_write_file(series_path_1, expected_time_serie)
_write_file(series_path_2, expected_time_serie)

# Check matrix
matrix = thermal.get_prepro_data_matrix()
matrix_1 = thermal.get_prepro_modulation_matrix()
matrix_2 = thermal.get_series_matrix()
matrix_3 = thermal.get_co2_cost_matrix()
matrix_4 = thermal.get_fuel_cost_matrix()

pd.testing.assert_frame_equal(matrix.astype(str), expected_time_serie.astype(str), check_dtype=False)
pd.testing.assert_frame_equal(matrix_1.astype(str), expected_time_serie.astype(str), check_dtype=False)
pd.testing.assert_frame_equal(matrix_2.astype(str), expected_time_serie.astype(str), check_dtype=False)
pd.testing.assert_frame_equal(matrix_3.astype(str), expected_time_serie.astype(str), check_dtype=False)
pd.testing.assert_frame_equal(matrix_4.astype(str), expected_time_serie.astype(str), check_dtype=False)

0 comments on commit e6ccad4

Please sign in to comment.