Skip to content

Commit

Permalink
Extend Nomenclature config to specify dimensions (#353)
Browse files Browse the repository at this point in the history
* Add dimensions attribute to config

* Use config.dimensions in DataStructureDefinition

* Add tests for config

* Add DataStructureDefinition config integration test

* Update docs

* Add subannual to allowed dimension values

* Adjust test with 'subannual'
  • Loading branch information
phackstock authored Jul 8, 2024
1 parent bccd352 commit 47cb3cb
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 3 deletions.
16 changes: 16 additions & 0 deletions docs/user_guide/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,19 @@ By setting *definitions.region.country* as *true* in the configuration file:
the nomenclature package will add all countries to the *region* codelist.

More details on the list of countries can be found here: :ref:`countries`.

Specify dimensions to be read
-----------------------------

The configuration file offers the possibility to set the dimensions which will be read
by *DataStructureDefinition*.

In the below case we specify *region*, *variable* and *scenario* to be read and used for
validation:

.. code:: yaml
dimensions:
- region
- variable
- scenario
10 changes: 10 additions & 0 deletions nomenclature/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from enum import Enum
from pathlib import Path
from typing import Annotated, Optional

Expand Down Expand Up @@ -132,7 +133,16 @@ class RegionMappingConfig(BaseModel):
model_config = ConfigDict(populate_by_name=True)


class DimensionEnum(str, Enum):
model = "model"
scenario = "scenario"
variable = "variable"
region = "region"
subannual = "subannual"


class NomenclatureConfig(BaseModel):
dimensions: None | list[DimensionEnum] = None
repositories: dict[str, Repository] = Field(default_factory=dict)
definitions: DataStructureConfig = Field(default_factory=DataStructureConfig)
mappings: RegionMappingConfig = Field(default_factory=RegionMappingConfig)
Expand Down
9 changes: 8 additions & 1 deletion nomenclature/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ def __init__(self, path, dimensions=None):
):
raise NotADirectoryError(f"Definitions directory not found: {path}")

self.dimensions = dimensions or ["region", "variable"]
self.dimensions = (
dimensions
or self.config.dimensions
or [
"region",
"variable",
]
)
for dim in self.dimensions:
codelist_cls = SPECIAL_CODELIST.get(dim, CodeList)
self.__setattr__(
Expand Down
2 changes: 2 additions & 0 deletions tests/data/general-config-only-country/nomenclature.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
dimensions:
- region
definitions:
region:
country: true
4 changes: 4 additions & 0 deletions tests/data/nomenclature_configs/dimensions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dimensions:
- region
- variable
- scenario
22 changes: 22 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,25 @@ def test_double_stacked_external_repo_raises(monkeypatch):
match = "External repos cannot again refer to external repos"
with raises(ValueError, match=match):
repo.check_external_repo_double_stacking()


def test_config_dimensions():
config = NomenclatureConfig.from_file(
TEST_DATA_DIR / "nomenclature_configs" / "dimensions.yaml"
)
assert set(config.dimensions) == {
"scenario",
"region",
"variable",
}


def test_invalid_config_dimensions_raises():
with raises(
ValueError,
match=(
"Input should be 'model', 'scenario', 'variable',"
" 'region' or 'subannual'"
),
):
NomenclatureConfig(dimensions=["year"])
3 changes: 1 addition & 2 deletions tests/test_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ def test_definition_from_general_config(workflow_folder):

def test_definition_general_config_country_only():
obs = DataStructureDefinition(
TEST_DATA_DIR / "general-config-only-country" / "definitions",
dimensions=["region"],
TEST_DATA_DIR / "general-config-only-country" / "definitions"
)
assert all(region in obs.region for region in ("Austria", "Bolivia", "Kosovo"))

Expand Down

0 comments on commit 47cb3cb

Please sign in to comment.