Source code for heavyedge.io.raw

"""Raw profile data files."""

import abc
import csv
import warnings
from pathlib import Path

import numpy as np

__all__ = [
    "RawProfileBase",
    "RawProfileCsvs",
]


def _deprecated(version, replace):
    removed_version = str(int(version.split(".")[0]) + 1) + ".0"

    def decorator(func):
        def wrapper(*args, **kwargs):
            warnings.warn(
                f"{func.__name__}() is deprecated since HeavyEdge {version} "
                f"and will be removed in {removed_version}. "
                f"Use {replace} instead.",
                category=DeprecationWarning,
                stacklevel=2,
            )
            return func(*args, **kwargs)

        return wrapper

    return decorator


[docs] class RawProfileBase(abc.ABC): """Base class to read raw profile data. All profiles must have the same length. Notes ----- ``self[key]`` returns a tuple of profile(s) and profile name(s). """ def __init__(self, path): self.path = Path(path).expanduser() def __len__(self): """Return number of profile data. .. note:: This method will be an abstract method in HeavyEdge 2.0. User should implement it with an efficient algorithm. """ return self.count_profiles() def __getitem__(self, key): """Return profile and name at index. .. note:: This method will be an abstract method in HeavyEdge 2.0. User should implement it with an efficient algorithm. """ return (self.all_profiles()[key], np.array(self.profile_names())[key]) @_deprecated("1.6", "__len__() method") @abc.abstractmethod def count_profiles(self): """Number of raw profiles. .. deprecated:: 1.6 This method will be removed in HeavyEdge 2.0. Implement __len__() and use len() instead. Returns ------- int """ @_deprecated("1.6", "__getitem__() method") def profiles(self): """Yield raw profiles. .. deprecated:: 1.6 This method will be removed in HeavyEdge 2.0. Implement __getitem__() and index the object instead. Yields ------ 1-D ndarray """ @_deprecated("1.6", "__getitem__() method") @abc.abstractmethod def all_profiles(self): """Return all profiles as an 2-D array. .. deprecated:: 1.6 This method will be removed in HeavyEdge 2.0. Implement __getitem__() and index the object instead. Returns ------- 2-D ndarray """ return np.array([p for p in self.profiles()]) @_deprecated("1.6", "__getitem__() method") @abc.abstractmethod def profile_names(self): """Yield profile names. .. deprecated:: 1.6 This method will be removed in HeavyEdge 2.0. Implement __getitem__() and index the object instead. Yields ------ str """
[docs] class RawProfileCsvs(RawProfileBase): """Read raw profile data from a directory containing CSV files. Directory structure: .. code-block:: rawdata/ ├── profile1.csv ├── profile2.csv └── ... Parameters ---------- path : pathlike Path to the directory containing the raw CSV files. Notes ----- - Each CSV file must contain a single column of numeric values (no header). - The order of profiles is determined by the sorted filenames. - The profile name is derived from the filename stem. Examples -------- >>> from heavyedge import get_sample_path, RawProfileCsvs >>> profiles = RawProfileCsvs(get_sample_path("Type3")) >>> import matplotlib.pyplot as plt # doctest: +SKIP ... for i in range(len(profiles)): ... profile, _ = profiles[i] ... plt.plot(profile) """ def __init__(self, path): super().__init__(path) self._files = sorted(self.path.glob("*.csv")) def __len__(self): return len(self._files) @staticmethod def _read_profile(path): with open(path, newline="") as csvfile: reader = csv.reader(csvfile) profile = np.array([float(row[0]) for row in reader]) return profile def __getitem__(self, key): file = self._files[key] return (self._read_profile(file), str(file.stem)) def count_profiles(self): # TODO: remove in HeavyEdge 2.0 return len(self) def profiles(self): # TODO: remove in HeavyEdge 2.0 for file in self._files: yield self._read_profile(file) def profile_names(self): # TODO: remove in HeavyEdge 2.0 for f in self._files: yield str(f.stem)