Skip to content

Commit 682b639

Browse files
committed
Use fixer prototype package
1 parent 5ce99eb commit 682b639

3 files changed

Lines changed: 35 additions & 29 deletions

File tree

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ commands:
9595
mamba env create -n esmvaltool -f environment.yml |& tee /logs/conda.txt
9696
git stash # Restore repository state to get clean version number.
9797
conda activate esmvaltool
98+
pip install git+https://github.com/ESMValGroup/fixer-prototype.git
9899
pip install --no-deps << parameters.flags >> ".[<<parameters.extra>>]" << parameters.upstream_packages >> |& tee /logs/install.txt
99100
- run:
100101
name: Log versions

esmvalcore/config/configurations/data-xcube-esacci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ projects:
88
type: "esmvalcore.io.xcube.XCubeDataSource"
99
data_store_id: "ccizarr"
1010
priority: 1
11+
values:
12+
short_name:
13+
prw: tcwv
1114
esa-cci-kc:
1215
type: "esmvalcore.io.xcube.XCubeDataSource"
1316
data_store_id: "esa-cci-kc"

esmvalcore/io/xcube.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
from dataclasses import dataclass, field
1919
from typing import TYPE_CHECKING, Any
2020

21-
import iris.cube
22-
import iris.std_names
2321
import xcube.core.store
22+
from fixer import fix
2423

2524
import esmvalcore.io.protocol
2625
from esmvalcore.iris_helpers import dataset_to_iris
2726

2827
if TYPE_CHECKING:
28+
import iris.cube
29+
2930
from esmvalcore.typing import Facets, FacetValue
3031

3132

@@ -92,22 +93,8 @@ def to_iris(self) -> iris.cube.CubeList:
9293
The loaded data.
9394
"""
9495
dataset = self.store.open_data(self.name, **self.open_params)
95-
# Keep only variables matching the "short_name" facet.
96-
short_names = self.facets.get("short_name", [])
97-
if isinstance(short_names, str | int):
98-
short_names = [str(short_names)]
99-
if short_names:
100-
dataset = dataset[short_names]
101-
102-
# Drop invalid standard_names.
103-
# TODO: move this to a standalone fixes package.
104-
for data_var in dataset.data_vars.values():
105-
if (
106-
"standard_name" in data_var.attrs
107-
and data_var.attrs["standard_name"]
108-
not in iris.std_names.STD_NAMES
109-
):
110-
data_var.attrs.pop("standard_name")
96+
dataset = fix(dataset, self.name)
97+
dataset.attrs["source_file"] = repr(self)
11198

11299
# Cache the attributes.
113100
self.attributes = copy.deepcopy(dataset.attrs)
@@ -140,6 +127,9 @@ class XCubeDataSource(esmvalcore.io.protocol.DataSource):
140127
<https://xcube.readthedocs.io/en/latest/dataaccess.html#available-data-stores>`__.
141128
"""
142129

130+
values: dict[str, dict[str, str]] = field(default_factory=dict)
131+
"""Mapping between the ESMValCore and xcube facet values."""
132+
143133
data_store_params: dict[str, Any] = field(default_factory=dict, repr=False)
144134
"""Parameters to use when creating the data store."""
145135

@@ -168,6 +158,10 @@ def find_data(self, **facets: FacetValue) -> list[XCubeDataset]: # noqa: C901,P
168158
requested_short_names = facets.get("short_name", "*")
169159
if isinstance(requested_short_names, str | int | float):
170160
requested_short_names = [str(requested_short_names)]
161+
requested_xcube_short_names = [
162+
self.values.get("short_name", {}).get(short_name, short_name)
163+
for short_name in requested_short_names
164+
]
171165
requested_datasets = facets.get("dataset", "*")
172166
if isinstance(requested_datasets, str | int | float):
173167
requested_datasets = [str(requested_datasets)]
@@ -184,19 +178,19 @@ def find_data(self, **facets: FacetValue) -> list[XCubeDataset]: # noqa: C901,P
184178
for dataset_pattern in requested_datasets:
185179
if fnmatch.fnmatchcase(data_id, dataset_pattern):
186180
description = store.describe_data(data_id)
187-
available_short_names = list(description.data_vars)
188-
short_names = [
181+
available_xcube_short_names = list(description.data_vars)
182+
xcube_short_names = [
189183
short_name
190-
for short_name in available_short_names
191-
for short_name_pattern in requested_short_names
184+
for short_name in available_xcube_short_names
185+
for short_name_pattern in requested_xcube_short_names
192186
if fnmatch.fnmatchcase(short_name, short_name_pattern)
193187
]
194-
if not short_names:
188+
if not xcube_short_names:
195189
logger.debug(
196-
"No variable matching % found in %s. Available variables are: %s",
197-
requested_short_names,
190+
"No variable matching %s found in %s. Available variables are: %s",
191+
requested_xcube_short_names,
198192
data_id,
199-
", ".join(sorted(available_short_names)),
193+
", ".join(sorted(available_xcube_short_names)),
200194
)
201195
continue
202196

@@ -206,12 +200,12 @@ def find_data(self, **facets: FacetValue) -> list[XCubeDataset]: # noqa: C901,P
206200
open_params = copy.deepcopy(self.open_params)
207201
open_params_schema = store.get_open_data_params_schema()
208202
if "variable_names" in open_params_schema.properties:
209-
open_params["variable_names"] = short_names
203+
open_params["variable_names"] = xcube_short_names
210204
elif "drop_variables" in open_params_schema.properties:
211205
drop_variables = {
212206
short_name
213-
for short_name in available_short_names
214-
if short_name not in short_names
207+
for short_name in available_xcube_short_names
208+
if short_name not in xcube_short_names
215209
}
216210
for coord in description.coords.values():
217211
if bound_var := coord.attrs.get("bounds"):
@@ -228,6 +222,14 @@ def find_data(self, **facets: FacetValue) -> list[XCubeDataset]: # noqa: C901,P
228222
"-",
229223
"",
230224
)
225+
short_names = [
226+
short_name
227+
for short_name, xcube_short_name in self.values.get(
228+
"short_name",
229+
{},
230+
).items()
231+
if xcube_short_name in xcube_short_names
232+
]
231233
dataset = XCubeDataset(
232234
name=data_id,
233235
facets={

0 commit comments

Comments
 (0)