diff --git a/pyproject.toml b/pyproject.toml index 96096a5..736bffc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,6 @@ where = ["src"] testpaths = ["tests"] [tool.uv.sources] -mxalign = { git = "https://github.com/mlwp-tools/mxalign", rev = "e2232d93275c7508897a7ddb0cce8b508665f24c" } mlwp-data-specs = { git = "https://github.com/mlwp-tools/mlwp-data-specs", rev = "059f382" } [dependency-groups] @@ -52,6 +51,5 @@ dev = [ "pooch>=1.9.0", ] test = [ - "mxalign", "pooch", ] diff --git a/src/mlwp_data_loaders/mxalign_api.py b/src/mlwp_data_loaders/mxalign_api.py deleted file mode 100644 index fb5c4ec..0000000 --- a/src/mlwp_data_loaders/mxalign_api.py +++ /dev/null @@ -1,102 +0,0 @@ -"""Helpers for validating datasets with local mxalign property checks.""" - -from __future__ import annotations - -from functools import lru_cache -from typing import Any - -import xarray as xr -from mlwp_data_specs.specs.reporting import ValidationReport - - -@lru_cache(maxsize=1) -def _load_mxalign_validation_symbols() -> dict[str, Any]: - """Load mxalign property validation modules from the installed package. - - Returns - ------- - dict[str, Any] - A dictionary containing the loaded mxalign classes and functions. - - Raises - ------ - ImportError - If the mxalign package is not installed or the required modules cannot be loaded. - """ - try: - from mxalign.properties.properties import Properties, Space, Time, Uncertainty - from mxalign.properties.validation import validate_dataset - except ImportError as e: - raise ImportError(f"mxalign package is not installed: {e}") - - return { - "Properties": Properties, - "Space": Space, - "Time": Time, - "Uncertainty": Uncertainty, - "validate_dataset": validate_dataset, - } - - -def validate_dataset_with_mxalign( - ds: xr.Dataset | xr.DataArray, - *, - time: str | None = None, - space: str | None = None, - uncertainty: str | None = None, -) -> ValidationReport: - """Validate a dataset with mxalign property checks when selectors are known. - - Parameters - ---------- - ds : xr.Dataset | xr.DataArray - The xarray dataset or data array to validate. - time : str | None, optional - The time profile to validate against. - space : str | None, optional - The space profile to validate against. - uncertainty : str | None, optional - The uncertainty profile to validate against. Defaults to "deterministic". - - Returns - ------- - ValidationReport - A validation report object containing the results of the mxalign checks. - """ - report = ValidationReport() - if time is None or space is None: - return report - - try: - mxalign = _load_mxalign_validation_symbols() - except ImportError as e: - report.add( - "MXAlign Properties", - "mxalign.properties.validation", - "WARNING", - f"mxalign not available for validation: {e}", - ) - return report - - properties = mxalign["Properties"]( - time=mxalign["Time"](time), - space=mxalign["Space"](space), - uncertainty=mxalign["Uncertainty"](uncertainty or "deterministic"), - ) - - try: - mxalign["validate_dataset"](ds, properties) - except ValueError as exc: - report.add( - "MXAlign Properties", - "mxalign.properties.validation.validate_dataset", - "FAIL", - str(exc), - ) - else: - report.add( - "MXAlign Properties", - "mxalign.properties.validation.validate_dataset", - "PASS", - ) - return report diff --git a/tests/test_anemoi_datasets_integration.py b/tests/test_anemoi_datasets_integration.py index 8c7df9c..e0a56ed 100644 --- a/tests/test_anemoi_datasets_integration.py +++ b/tests/test_anemoi_datasets_integration.py @@ -2,14 +2,7 @@ from __future__ import annotations -from mlwp_data_specs.api import ( - SPACE_TRAIT_ATTR, - TIME_TRAIT_ATTR, - UNCERTAINTY_TRAIT_ATTR, -) - from mlwp_data_loaders.api import load_and_validate_dataset -from mlwp_data_loaders.mxalign_api import validate_dataset_with_mxalign # Use small CERRA sample dataset stored on EWC (European Weather Cloud) # S3-compatible object store for testing. @@ -36,18 +29,6 @@ def test_load_dataset_opens_anemoi_store_from_ewc() -> None: return_validation_report=True, ) - # Note: mxalign validation is temporarily kept here during early development - # to ensure `mlwp-data-specs` behaves identically. It will eventually be removed. - report_mxalign = validate_dataset_with_mxalign( - ds, - time=ds.attrs.get(TIME_TRAIT_ATTR), - space=ds.attrs.get(SPACE_TRAIT_ATTR), - uncertainty=ds.attrs.get(UNCERTAINTY_TRAIT_ATTR), - ) - if report_mxalign.has_fails(): - report_mxalign.console_print() - assert not report_mxalign.has_fails() - if report_specs.has_fails(): report_specs.console_print() assert not report_specs.has_fails() diff --git a/tests/test_anemoi_inference_loader.py b/tests/test_anemoi_inference_loader.py index 5b25dbc..3ab60cc 100644 --- a/tests/test_anemoi_inference_loader.py +++ b/tests/test_anemoi_inference_loader.py @@ -2,14 +2,7 @@ from __future__ import annotations -from mlwp_data_specs.api import ( - SPACE_TRAIT_ATTR, - TIME_TRAIT_ATTR, - UNCERTAINTY_TRAIT_ATTR, -) - from mlwp_data_loaders.api import load_and_validate_dataset -from mlwp_data_loaders.mxalign_api import validate_dataset_with_mxalign DATASET_PATH = [ "s3://mlwp-sample-datasets/anemoi-inference/unknown-revision/" @@ -37,16 +30,6 @@ def test_load_dataset_opens_anemoi_inference_from_ewc() -> None: return_validation_report=True, ) - report_mxalign = validate_dataset_with_mxalign( - ds, - time=ds.attrs.get(TIME_TRAIT_ATTR), - space=ds.attrs.get(SPACE_TRAIT_ATTR), - uncertainty=ds.attrs.get(UNCERTAINTY_TRAIT_ATTR), - ) - if report_mxalign.has_fails(): - report_mxalign.console_print() - assert not report_mxalign.has_fails() - if report_specs.has_fails(): report_specs.console_print() assert not report_specs.has_fails() diff --git a/tests/test_api.py b/tests/test_api.py index 591abce..212b37f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -5,34 +5,10 @@ import pytest import xarray as xr -import mlwp_data_loaders.mxalign_api as mxalign_api from mlwp_data_loaders.api import load_and_validate_dataset from mlwp_data_loaders.core import get_loader_func -def _forecast_grid_ds() -> xr.Dataset: - """Create a forecast + grid dataset for loader tests.""" - ds = xr.Dataset( - coords={ - "reference_time": ("reference_time", [0]), - "lead_time": ("lead_time", [1]), - "longitude": ("longitude", [10.0, 11.0]), - "latitude": ("latitude", [60.0, 61.0]), - } - ) - ds.coords["reference_time"].attrs["standard_name"] = "forecast_reference_time" - ds.coords["lead_time"].attrs.update( - {"standard_name": "forecast_period", "units": "hours"} - ) - ds.coords["longitude"].attrs.update( - {"standard_name": "longitude", "units": "degrees_east"} - ) - ds.coords["latitude"].attrs.update( - {"standard_name": "latitude", "units": "degrees_north"} - ) - return ds - - def test_get_loader_func_raises_missing_load_dataset(tmp_path) -> None: """Loader modules must define a 'load_dataset' function.""" loader_file = tmp_path / "loader_missing.py" @@ -109,37 +85,3 @@ def has_fails(self): assert isinstance(ds, xr.Dataset) assert not report.has_fails() assert ds.attrs.get("mlwp_time_trait") == "forecast" - - -def test_validate_dataset_with_mxalign_returns_fail_report_for_invalid_dims( - monkeypatch: pytest.MonkeyPatch, -) -> None: - """mxalign validation failures are converted into report entries.""" - - def mock_load_symbols(): - def mock_validate(ds, props): - raise ValueError("Mock mxalign validation failed") - - return { - "Properties": lambda time, space, uncertainty: "props", - "Space": lambda x: x, - "Time": lambda x: x, - "Uncertainty": lambda x: x, - "validate_dataset": mock_validate, - } - - monkeypatch.setattr( - "mlwp_data_loaders.mxalign_api._load_mxalign_validation_symbols", - mock_load_symbols, - ) - - report = mxalign_api.validate_dataset_with_mxalign( - _forecast_grid_ds(), - time="observation", - space="point", - uncertainty="deterministic", - ) - - assert report.has_fails() - assert len(report.results) == 1 - assert report.results[0].section == "MXAlign Properties" diff --git a/tests/test_harp_obstable_integration.py b/tests/test_harp_obstable_integration.py index f834f12..5ffa544 100644 --- a/tests/test_harp_obstable_integration.py +++ b/tests/test_harp_obstable_integration.py @@ -4,14 +4,8 @@ import pooch import pytest -from mlwp_data_specs.api import ( - SPACE_TRAIT_ATTR, - TIME_TRAIT_ATTR, - UNCERTAINTY_TRAIT_ATTR, -) from mlwp_data_loaders.api import load_and_validate_dataset -from mlwp_data_loaders.mxalign_api import validate_dataset_with_mxalign HARP_DATA_URL = "https://raw.githubusercontent.com/harphub/harpData/master/inst/OBSTABLE/OBSTABLE_2019.sqlite" HARP_DATA_HASH = "bdab991c287a41871488456d1a9d697942aa3a612800a88264defa312a9d637b" @@ -35,18 +29,6 @@ def test_load_dataset_opens_harp_obstable(obstable_path: str) -> None: return_validation_report=True, ) - # Note: mxalign validation is temporarily kept here during early development - # to ensure `mlwp-data-specs` behaves identically. It will eventually be removed. - report_mxalign = validate_dataset_with_mxalign( - ds, - time=ds.attrs.get(TIME_TRAIT_ATTR), - space=ds.attrs.get(SPACE_TRAIT_ATTR), - uncertainty=ds.attrs.get(UNCERTAINTY_TRAIT_ATTR), - ) - if report_mxalign.has_fails(): - report_mxalign.console_print() - assert not report_mxalign.has_fails() - if report_specs.has_fails(): report_specs.console_print() assert not report_specs.has_fails()