-
Notifications
You must be signed in to change notification settings - Fork 12
feat(reserves): support thermal reserves #3280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
156 commits
Select commit
Hold shift + click to select a range
1327f49
start writing the code
MartinBelthle 16e0a76
fixing
MartinBelthle d9482cc
c
MartinBelthle ddbfe0a
c
MartinBelthle 0bee06f
c
MartinBelthle 46644d2
start writing test to ensure nothing broke
MartinBelthle 69d9e3e
continue
MartinBelthle 219af13
implement deletion
MartinBelthle 03f5acb
add empty skeleton
MartinBelthle 6957f2f
adapt study converter
MartinBelthle a67e302
brevet
MartinBelthle a186dfd
fixing mypy
MartinBelthle 486d6e6
fixing mypy issues
MartinBelthle 6febe37
write code
MartinBelthle 0ed7d8b
c
MartinBelthle f44798a
create one command
MartinBelthle ced952b
introduce second command
MartinBelthle d415ecf
fixing ruff and mypy
MartinBelthle ec5a90c
a
MartinBelthle ad88bf9
typo
MartinBelthle 1d887ce
fix copilot issue
MartinBelthle f10e606
clean thermal in fs mode
MartinBelthle ad3af53
write deletion code even if it does not work for now
MartinBelthle b8093c9
bien
MartinBelthle 98c7792
add alembic migration
MartinBelthle 639b1a5
start creating skeletons
MartinBelthle b6a3e7f
add in memory code
MartinBelthle bdf5aa2
c
MartinBelthle 58c30b6
start filling
MartinBelthle e59ff97
add UTs for merge function
MartinBelthle 42372f1
simplify a bit the function
MartinBelthle fa4b169
fixing mypy issues
MartinBelthle df24615
add unicity verification
MartinBelthle bf2b6c6
start renaming as symmetries would we merged
MartinBelthle 1b11cf9
f
MartinBelthle 03f6f17
c
MartinBelthle 811b1cf
c
MartinBelthle 1185cd7
c
MartinBelthle c749c4c
continue
MartinBelthle 0df636d
introduce symmetries_check
MartinBelthle b6a183b
reuse other exception
MartinBelthle c3c8a92
finalize DB implem
MartinBelthle 2339ff4
no mypy issue
MartinBelthle 05e81f2
study converter
MartinBelthle 4f9cf90
c
MartinBelthle 0198e5d
mama
MartinBelthle 496a99c
put code in common
MartinBelthle a903b7c
implement the deletion
MartinBelthle 9958c18
add commen
MartinBelthle 4e8dd54
change serialization method
MartinBelthle 293eb0b
finalize dao code
MartinBelthle 01c71c6
fix thermal removal issues
MartinBelthle f708b85
remove method
MartinBelthle cda36b7
add 2nd command
MartinBelthle a21d421
implement manager
MartinBelthle 144954c
remove deletion code
MartinBelthle 8eca53c
build the managers
MartinBelthle 749fd35
introduce 2nd endpoint
MartinBelthle 22d93c7
Merge branch 'dev' into feat/support-thermal-reserves
MartinBelthle e16bbf6
remove cmd
MartinBelthle 36b34bc
start rewriting code for new endpoints
MartinBelthle fbfe261
typo
MartinBelthle 0d1689e
ice
MartinBelthle 419258a
create new cmd
MartinBelthle 94b9cae
fix
MartinBelthle 32d79ee
f
MartinBelthle 813acce
continue refactoring
MartinBelthle 4be569f
c
MartinBelthle 40ae3ca
c
MartinBelthle 90b225d
c
MartinBelthle bf693b3
fix import issue
MartinBelthle 73695a9
fix DB code issue
MartinBelthle ae34556
start rewriting
MartinBelthle 4737d6e
type ignore
MartinBelthle 8b576e8
not done yet
MartinBelthle 5633129
no mypy issue anymroe
MartinBelthle c7c9a4a
Merge branch 'dev' into feat/support-thermal-reserves
MartinBelthle 6ed6a48
adapt new code
MartinBelthle 15fde8e
add comment
MartinBelthle f1954fb
continue
MartinBelthle 9662b68
add certifications endpoint
MartinBelthle af738f0
typo
MartinBelthle bb26626
fix issue
MartinBelthle 5adcf18
implement the DB code
MartinBelthle c6ed3f9
start writing cmd UT
MartinBelthle 37bb4fb
finalize set up code
MartinBelthle ce300e8
typo
MartinBelthle 9137227
continue
MartinBelthle 28482a4
continue
MartinBelthle f368bcc
c
MartinBelthle 056a4f9
fix fs behavior
MartinBelthle b70af86
finalize error case test
MartinBelthle ba7feb8
fix fs code
MartinBelthle 9d3a27c
add first logic test
MartinBelthle 418a278
c
MartinBelthle 3f862fa
fix
MartinBelthle 5839007
finalize UT
MartinBelthle f27f992
fix src code
MartinBelthle e7616e1
continue
MartinBelthle 1cf4e17
error test ok on DB but not on FS
MartinBelthle 69c15c1
error test ok
MartinBelthle 7062904
start real test
MartinBelthle 85e522e
fix certification order inside db code
MartinBelthle 87f5181
forgot to save the yaml content
MartinBelthle 8a495ee
fix parsing code
MartinBelthle f8c068d
test okay for FS but not for DB
MartinBelthle 983adc1
fix db code
MartinBelthle 4d023e6
start writing command factory test
MartinBelthle 8c033cd
test is ok
MartinBelthle 5228595
set up the FS test
MartinBelthle 2e239c8
start writing test
MartinBelthle 2365156
handle error case
MartinBelthle fe2da43
rename
MartinBelthle cd4a774
c
MartinBelthle a7bbf97
finalize UT for FS
MartinBelthle 93993bb
Merge branch 'dev' into feat/support-thermal-reserves
MartinBelthle a8d56d2
fix alembic migration merge
MartinBelthle 14ebfcc
remove merge_symmetries method
MartinBelthle 68d51aa
add sorting as a validator
MartinBelthle a5cf7a3
rename files
MartinBelthle 0a04bd8
write UT that currently fails
MartinBelthle f3275ac
continue
MartinBelthle e808df1
now test is passing
MartinBelthle 5ebdf6c
make test storage mode parametrized
MartinBelthle f43d321
fix tets
MartinBelthle 31151ab
move test
MartinBelthle 81373e8
TDD
MartinBelthle 525e87b
simplify exception raised
MartinBelthle 53fd2b1
introduce common code
MartinBelthle f4eef45
continue
MartinBelthle 8850a44
test is ok for both storage modes
MartinBelthle 000607d
add deletion tests
MartinBelthle efbe2e6
add the same test for symmetries
MartinBelthle ed76d49
fix code to make test work
MartinBelthle 3bb5d5f
Merge branch 'dev' into feat/support-thermal-reserves
MartinBelthle 317bbb7
fix failing test
MartinBelthle c2edf21
resolve conflicts with dev
MartinBelthle 6fd2bb2
fix src code
MartinBelthle 868bb00
start building big pydantic model
MartinBelthle 2faa37f
continue moving code
MartinBelthle 9e0307f
error cases test is ok
MartinBelthle 0b69634
add another parsing test
MartinBelthle e10e00d
create structure
MartinBelthle 7c2a1bb
c
MartinBelthle 96a8e6c
c
MartinBelthle e50362c
one less error
MartinBelthle 57f8ad8
c
MartinBelthle fdf0a48
start fixing
MartinBelthle cd1afd8
no mypy issue
MartinBelthle b08fb49
typo
MartinBelthle 98791f4
c
MartinBelthle 70b7136
test is now ok
MartinBelthle 38695bf
Merge branch 'dev' into feat/support-thermal-reserves
MartinBelthle 06db558
make free function from static method
MartinBelthle bbff505
document the design notes
MartinBelthle 719491b
fix symmetries deletion test
MartinBelthle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| """add_thermal_reserve_tables | ||
|
|
||
| Revision ID: 665f7b1d7575 | ||
| Revises: 80fdf2408ede | ||
| Create Date: 2026-06-23 13:41:03.310148 | ||
|
|
||
| """ | ||
| from alembic import op | ||
| import sqlalchemy as sa | ||
|
|
||
|
|
||
| # revision identifiers, used by Alembic. | ||
| revision = '665f7b1d7575' | ||
| down_revision = '80fdf2408ede' | ||
| branch_labels = None | ||
| depends_on = None | ||
|
|
||
|
|
||
| def upgrade() -> None: | ||
| # Certifications | ||
| op.create_table( | ||
| "thermal_reserve_certifications", | ||
| sa.Column("study_id", sa.String(36), nullable=False), | ||
| sa.Column("area_id", sa.String(255), nullable=False), | ||
| sa.Column("thermal_id", sa.String(255), nullable=False), | ||
| sa.Column("reserve_id", sa.String(255), nullable=False), | ||
| sa.Column("max_power", sa.Float(), nullable=False), | ||
| sa.Column("max_power_off", sa.Float(), nullable=False), | ||
| sa.Column("participation_cost", sa.Float(), nullable=False), | ||
| sa.Column("participation_cost_off", sa.Float(), nullable=False), | ||
| sa.ForeignKeyConstraint( | ||
| ["study_id", "area_id", "thermal_id"], | ||
| ["thermal_cluster.study_id", "thermal_cluster.area_id", "thermal_cluster.thermal_id"], | ||
| ondelete="CASCADE", | ||
| ), | ||
| sa.ForeignKeyConstraint( | ||
| ["study_id", "area_id", "reserve_id"], | ||
| ["reserve_definition.study_id", "reserve_definition.area_id", "reserve_definition.reserve_id"], | ||
| ondelete="CASCADE", | ||
| ), | ||
| sa.PrimaryKeyConstraint("study_id", "area_id", "thermal_id", "reserve_id"), | ||
| ) | ||
|
|
||
| # Symmetries | ||
| op.create_table( | ||
| "thermal_reserve_symmetries", | ||
| sa.Column("study_id", sa.String(36), nullable=False), | ||
| sa.Column("area_id", sa.String(255), nullable=False), | ||
| sa.Column("thermal_id", sa.String(255), nullable=False), | ||
| sa.Column("symmetries", sa.String(), nullable=False), | ||
| sa.ForeignKeyConstraint( | ||
| ["study_id", "area_id", "thermal_id"], | ||
| ["thermal_cluster.study_id", "thermal_cluster.area_id", "thermal_cluster.thermal_id"], | ||
| ondelete="CASCADE", | ||
| ), | ||
| sa.PrimaryKeyConstraint("study_id", "area_id", "thermal_id"), | ||
| ) | ||
|
|
||
|
|
||
| def downgrade() -> None: | ||
| op.drop_table("thermal_reserve_certifications") | ||
| op.drop_table("thermal_reserve_symmetries") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
antarest/study/business/areas/reserve_certification_management.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # Copyright (c) 2026, RTE (https://www.rte-france.com) | ||
| # | ||
| # See AUTHORS.txt | ||
| # | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| # | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # | ||
| # This file is part of the Antares project. | ||
| from antarest.study.business.model.thermal_reserve_certification_model import ( | ||
| ReserveCertifications, | ||
| ) | ||
| from antarest.study.business.study_interface import StudyInterface | ||
| from antarest.study.storage.variantstudy.model.command.icommand import ICommand | ||
| from antarest.study.storage.variantstudy.model.command.replace_thermal_reserve_certifications import ( | ||
| ReplaceThermalReserveCertifications, | ||
| ) | ||
| from antarest.study.storage.variantstudy.model.command_context import CommandContext | ||
|
|
||
|
|
||
| class ReserveCertificationsManager: | ||
| def __init__(self, command_context: CommandContext) -> None: | ||
| self._command_context = command_context | ||
|
|
||
| def get_certifications(self, study: StudyInterface, area_id: str) -> ReserveCertifications: | ||
| thermals = study.get_study_dao().get_thermal_reserve_certifications(area_id) | ||
| return ReserveCertifications(thermals=thermals) | ||
|
|
||
| def set_certifications( | ||
| self, | ||
| study: StudyInterface, | ||
| area_id: str, | ||
| data: ReserveCertifications, | ||
| ) -> ReserveCertifications: | ||
| commands: list[ICommand] = [] | ||
|
|
||
| # Thermals part | ||
| if data.thermals: | ||
| command = ReplaceThermalReserveCertifications( | ||
| area_id=area_id, | ||
| certifications=data.thermals, | ||
| study_version=study.version, | ||
| command_context=self._command_context, | ||
| ) | ||
| commands.append(command) | ||
|
|
||
| # St-Storage part | ||
| # todo | ||
|
|
||
| # Hydro part | ||
| # todo | ||
|
|
||
| # Apply the modifications | ||
| if commands: | ||
| study.add_commands(commands) | ||
| return data | ||
38 changes: 38 additions & 0 deletions
38
antarest/study/business/areas/reserve_symmetries_management.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Copyright (c) 2026, RTE (https://www.rte-france.com) | ||
| # | ||
| # See AUTHORS.txt | ||
| # | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| # | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # | ||
| # This file is part of the Antares project. | ||
| from antarest.study.business.model.reserve_symmetries_model import ReserveSymmetries | ||
| from antarest.study.business.study_interface import StudyInterface | ||
| from antarest.study.dao.common import ThermalId | ||
| from antarest.study.storage.variantstudy.model.command.replace_thermal_reserve_symmetries import ( | ||
| ReplaceThermalReserveSymmetries, | ||
| ) | ||
| from antarest.study.storage.variantstudy.model.command_context import CommandContext | ||
|
|
||
|
|
||
| class ReserveSymmetriesManager: | ||
| def __init__(self, command_context: CommandContext) -> None: | ||
| self._command_context = command_context | ||
|
|
||
| def get_thermal_symmetries(self, study: StudyInterface, area_id: str) -> dict[ThermalId, ReserveSymmetries]: | ||
| return study.get_study_dao().get_thermal_reserve_symmetries(area_id) | ||
|
|
||
| def set_thermal_symmetries( | ||
| self, study: StudyInterface, area_id: str, data: dict[ThermalId, ReserveSymmetries] | ||
| ) -> dict[ThermalId, ReserveSymmetries]: | ||
| command = ReplaceThermalReserveSymmetries( | ||
| area_id=area_id, | ||
| symmetries=data, | ||
| command_context=self._command_context, | ||
| study_version=study.version, | ||
| ) | ||
| study.add_commands([command]) | ||
| return data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # Copyright (c) 2026, RTE (https://www.rte-france.com) | ||
| # | ||
| # See AUTHORS.txt | ||
| # | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| # | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # | ||
| # This file is part of the Antares project. | ||
| from typing import Annotated, TypeAlias | ||
|
|
||
| from pydantic import BeforeValidator | ||
|
|
||
| from antarest.study.business.model.reserve_definition_model import ReserveDefinitionId | ||
|
|
||
|
|
||
| def _symmetry_validator(data: list[str]) -> list[str]: | ||
| if len(data) < 2: | ||
| raise ValueError(f"Reserve symmetries should have at least 2 elements, and was {data}") | ||
| if len(set(data)) != len(data): | ||
| raise ValueError(f"Reserve symmetries should not contain duplicates, and was {data}") | ||
| return sorted(data) | ||
|
|
||
|
|
||
| ReserveSymmetry: TypeAlias = Annotated[list[ReserveDefinitionId], BeforeValidator(_symmetry_validator)] | ||
| ReserveSymmetries: TypeAlias = list[ReserveSymmetry] |
49 changes: 49 additions & 0 deletions
49
antarest/study/business/model/thermal_reserve_certification_model.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # Copyright (c) 2026, RTE (https://www.rte-france.com) | ||
| # | ||
| # See AUTHORS.txt | ||
| # | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| # | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # | ||
| # This file is part of the Antares project. | ||
| from typing import Annotated, TypeAlias | ||
|
|
||
| from pydantic import ConfigDict, Field | ||
| from pydantic.alias_generators import to_camel | ||
|
|
||
| from antarest.core.serde import AntaresBaseModel | ||
| from antarest.study.business.model.reserve_definition_model import ReserveDefinitionId | ||
|
|
||
| Cost = Annotated[float, Field(ge=0)] | ||
| Power = Annotated[float, Field(ge=0)] | ||
|
|
||
| ########################## | ||
| # Thermal part | ||
| ########################## | ||
|
|
||
|
|
||
| class ThermalReserveCertification(AntaresBaseModel): | ||
| model_config = ConfigDict(alias_generator=to_camel, extra="forbid", populate_by_name=True) | ||
|
|
||
| max_power: Power = 0.0 | ||
| max_power_off: Power = 0.0 | ||
| participation_cost: Cost = 0.0 | ||
| participation_cost_off: Cost = 0.0 | ||
|
|
||
|
|
||
| ThermalId: TypeAlias = str | ||
| ThermalReserveCertificationMapping = dict[ReserveDefinitionId, dict[ThermalId, ThermalReserveCertification]] | ||
|
|
||
|
|
||
| ########################## | ||
| # Whole model | ||
| ########################## | ||
|
|
||
|
|
||
| class ReserveCertifications(AntaresBaseModel): | ||
| model_config = ConfigDict(alias_generator=to_camel, extra="forbid", populate_by_name=True) | ||
|
|
||
| thermals: ThermalReserveCertificationMapping |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # Copyright (c) 2026, RTE (https://www.rte-france.com) | ||
| # | ||
| # See AUTHORS.txt | ||
| # | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| # | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # | ||
| # This file is part of the Antares project. | ||
| from antarest.study.business.model.reserve_definition_model import ReserveDefinitionId | ||
| from antarest.study.business.model.reserve_symmetries_model import ReserveSymmetries | ||
|
|
||
|
|
||
| def remove_reserve_symmetries_by_cascade( | ||
| symmetries_dict: dict[str, ReserveSymmetries], reserve_ids_to_remove: set[ReserveDefinitionId] | ||
| ) -> dict[str, ReserveSymmetries] | None: | ||
| """ | ||
| When removing a reserve, we should also remove it from the symmetries. | ||
|
|
||
| Returns: | ||
| The updated symmetries dictionary or None if no symmetries were updated. | ||
| """ | ||
| should_update_symmetries = False | ||
| for symmetries in symmetries_dict.values(): | ||
| for i, symmetry in enumerate(symmetries): | ||
| symmetries[i] = [reserve_id for reserve_id in symmetry if reserve_id not in reserve_ids_to_remove] | ||
| if len(symmetries[i]) != len(symmetry): | ||
| should_update_symmetries = True | ||
| if len(symmetries[i]) == 1: | ||
| # We only have one reserve left in the symmetry, we should remove it | ||
| symmetries[i] = [] | ||
| if should_update_symmetries: | ||
| return symmetries_dict | ||
| return None |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # Copyright (c) 2026, RTE (https://www.rte-france.com) | ||
| # | ||
| # See AUTHORS.txt | ||
| # | ||
| # This Source Code Form is subject to the terms of the Mozilla Public | ||
| # License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| # | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| # | ||
| # This file is part of the Antares project. | ||
| from abc import ABC, abstractmethod | ||
|
|
||
| from antarest.study.business.model.thermal_reserve_certification_model import ( | ||
| ThermalReserveCertificationMapping, | ||
| ) | ||
| from antarest.study.dao.common import AreaId | ||
|
|
||
|
|
||
| class ReadOnlyReserveCertificationDao(ABC): | ||
| @abstractmethod | ||
| def get_all_thermal_reserve_certifications(self) -> dict[AreaId, ThermalReserveCertificationMapping]: | ||
| """ | ||
| Returns the thermal reserve certifications of the whole study. | ||
|
|
||
| Design notes: | ||
| - If an area has no certification, it won't be present in the returned data. | ||
| - If a thermal cluster has no certification, it also won't be present in the returned data. | ||
|
|
||
| """ | ||
| raise NotImplementedError() | ||
|
|
||
| @abstractmethod | ||
| def get_thermal_reserve_certifications(self, area_id: AreaId) -> ThermalReserveCertificationMapping: | ||
| raise NotImplementedError() | ||
|
|
||
|
|
||
| class ReserveCertificationDao(ReadOnlyReserveCertificationDao): | ||
| @abstractmethod | ||
| def save_thermal_reserve_certifications(self, data: dict[AreaId, ThermalReserveCertificationMapping]) -> None: | ||
| """ | ||
| Replace the thermal reserve certifications with the given one. | ||
|
|
||
| Design notes: | ||
| - If an area is absent from the given data, its certifications are not modified. | ||
| - If a thermal cluster is absent from in the given data, its certifications will be removed. | ||
|
|
||
| """ | ||
| raise NotImplementedError() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.