Source code for pypielm.data.adapters.npz_adapter

"""NumPy .npz file adapter."""

from __future__ import annotations

from pathlib import Path

import numpy as np
import torch

from pypielm.data.dataset import PIELMDataset

_FIELD_KEYS = ("X_colloc", "X_bc", "y_bc", "X_ic", "y_ic", "X_data", "y_data")


[docs] class NPZAdapter: """Load a :class:`~pypielm.data.dataset.PIELMDataset` from a NumPy ``.npz`` file. Expected keys in the archive: ``'X_colloc'``, and optionally ``'X_bc'``, ``'y_bc'``, ``'X_ic'``, ``'y_ic'``, ``'X_data'``, ``'y_data'``. When no ``'X_colloc'`` key is present but the archive has exactly two arrays, the first is treated as ``X_colloc`` and the second as ``y_data``. Args: path: Path to the ``.npz`` file. dtype: Tensor dtype. device: Target device. """ def __init__( self, path: str | Path, dtype: torch.dtype = torch.float64, device: str | torch.device = "cpu", ) -> None: self.path = Path(path) self.dtype = dtype self.device = device
[docs] def load(self) -> PIELMDataset: """Load and return the dataset.""" with np.load(self.path, allow_pickle=False) as archive: keys = list(archive.files) data = {k: np.asarray(archive[k]) for k in keys} def _t(arr: np.ndarray) -> torch.Tensor: t = torch.tensor(arr, dtype=self.dtype, device=self.device) if t.ndim == 1: t = t.unsqueeze(1) return t if "X_colloc" in data: kwargs = {} for field in _FIELD_KEYS: if field in data: kwargs[field] = _t(data[field]) return PIELMDataset(**kwargs) # type: ignore[arg-type] # Fallback: two arrays → (X_colloc, y_data) if len(keys) == 2: return PIELMDataset( X_colloc=_t(data[keys[0]]), y_data=_t(data[keys[1]]), ) raise ValueError( f"NPZ file '{self.path}' has no 'X_colloc' key and does not contain " "exactly two arrays. Provide a file with standard field names." )