diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..a5008e4 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,36 @@ +# This workflow will upload a Python Package using Twine when a release is created +# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Upload Python Package + +on: + release: + types: [published] + +jobs: + deploy: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + - name: Build package + run: python -m build + - name: Publish package + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.EMD_PYPI_API_TOKEN }} diff --git a/.gitignore b/.gitignore index 907bac8..660e329 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,17 @@ -build -dist -*.swp -venv -.mypy_cache -.vscode +venv/ +.venv/ +build/ +dist/ *.egg-info + +.vscode/ +.idea/ + +.mypy_cache +__pycache__ +.pytest_cache/ +.ipynb_checkpoints/ + +*.swp *.pyc -*ipynb \ No newline at end of file +*.ipynb \ No newline at end of file diff --git a/PyEMD/CEEMDAN.py b/PyEMD/CEEMDAN.py index 2d81edb..77d4a70 100644 --- a/PyEMD/CEEMDAN.py +++ b/PyEMD/CEEMDAN.py @@ -39,6 +39,18 @@ class CEEMDAN: values. Two are `range_thr` and `total_power_thr` which relate to the value range (max - min) and check for total power below, respectively. + Configuration can be passed through keyword parameters. + For example, updating threshold would be through: + + Example 1: + + >>> config = {"range_thr": 0.001, "total_power_thr": 0.01} + >>> emd = EMD(**config) + + Example 2: + + >>> emd = EMD(range_thr=0.001, total_power_thr=0.01) + Parameters ---------- @@ -62,6 +74,17 @@ class CEEMDAN: processes : int or None (optional) Number of processes harness when executing in parallel mode. The value should be between 1 and max that depends on your hardware. + noise_scale : float (default: 1) + Scale (amplitude) of the added noise. + noise_kind : str (default: "normal") + What type of noise to add. Allowed are "normal" (default) and "uniform". + range_thr : float (default: 0.01) + Range threshold used as an IMF check. The value is in percentage compared + to initial signal's amplitude. If absolute amplitude (max - min) is below + the `range_thr` then the decomposition is finished. + total_power_thr : float (default: 0.05) + Signal's power threshold. Finishes decomposition if sum(abs(r)) < thr. + References ---------- @@ -80,16 +103,6 @@ class CEEMDAN: noise_kinds_all = ["normal", "uniform"] def __init__(self, trials: int=100, epsilon: float = 0.005, ext_EMD = None, parallel: bool = False, **kwargs): - """ - Configuration can be passed through keyword parameters. - For example, updating threshold would be through: - - Example 1: - >>> config = {"range_thr": 0.001, "total_power_thr": 0.01} - >>> emd = EMD(**config) - Example 2: - >>> emd = EMD(range_thr=0.001, total_power_thr=0.01) - """ # Ensemble constants self.trials = trials diff --git a/PyEMD/EMD.py b/PyEMD/EMD.py index 543cd62..9a644c6 100644 --- a/PyEMD/EMD.py +++ b/PyEMD/EMD.py @@ -887,7 +887,14 @@ def emd(self, S: np.ndarray, T: Optional[np.ndarray] = None, max_imf: int = -1) def get_imfs_and_residue(self) -> Tuple[np.ndarray, np.ndarray]: """ Provides access to separated imfs and residue from recently analysed signal. - :return: (imfs, residue) + + Returns + ------- + imfs : np.ndarray + Obtained IMFs + residue : np.ndarray + Residue. + """ if self.imfs is None or self.residue is None: raise ValueError('No IMF found. Please, run EMD method or its variant first.') @@ -900,7 +907,14 @@ def get_imfs_and_trend(self) -> Tuple[np.ndarray, np.ndarray]: Note that this may differ from the `get_imfs_and_residue` as the trend isn't necessarily the residue. Residue is a point-wise difference between input signal and all obtained components, whereas trend is the slowest component (can be zero). - :return: (imfs, trend) + + Returns + ------- + imfs : np.ndarray + Obtained IMFs + trend : np.ndarray + The main trend. + """ if self.imfs is None or self.residue is None: raise ValueError('No IMF found. Please, run EMD method or its variant first.') diff --git a/PyEMD/__init__.py b/PyEMD/__init__.py index 8579117..91c67d3 100644 --- a/PyEMD/__init__.py +++ b/PyEMD/__init__.py @@ -1,6 +1,6 @@ import logging -__version__ = "0.2.15" +__version__ = "1.0.0" logger = logging.getLogger('pyemd') from PyEMD.EMD import EMD diff --git a/doc/ceemdan.rst b/doc/ceemdan.rst index bdce0e7..9a8f4b2 100644 --- a/doc/ceemdan.rst +++ b/doc/ceemdan.rst @@ -7,9 +7,15 @@ Info Complete ensemble EMD with adaptive noise (CEEMDAN) performs an EEMD with the difference that the information about the noise is shared among all workers. + +.. note:: + Given the nature of CEEMDAN, each time you decompose a signal you will obtain a different set of components. + That's the expected consequence of adding noise which is going to be random and different. + To make the decomposition reproducible, one needs to set a seed for the random number generator used in CEEMDAN. + This is done using :func:`PyEMD.CEEMDAN.noise_seed` method on the instance. + Class ----- .. autoclass:: PyEMD.CEEMDAN :members: - :special-members: diff --git a/doc/eemd.rst b/doc/eemd.rst index f83f909..d05f1a3 100644 --- a/doc/eemd.rst +++ b/doc/eemd.rst @@ -3,6 +3,7 @@ EEMD Info ---- + Ensemble empirical mode decomposition (EEMD) creates an ensemble of worker each of which performs an :doc:`EMD ` on a copy of the input signal with added noise. When all workers finish their work a mean over all workers is considered as diff --git a/doc/examples.rst b/doc/examples.rst index 2bdfc89..d31541c 100644 --- a/doc/examples.rst +++ b/doc/examples.rst @@ -1,5 +1,5 @@ -Example -******* +Examples +******** Some examples can be found in PyEMD/example directory. diff --git a/doc/intro.rst b/doc/intro.rst index 5a24fc1..e182ab5 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -28,7 +28,9 @@ The easiest way is to either add `EMD-signal`_ to your `requirements.txt` file, $ pip install EMD-signal -And, yes, the package is updated every time there is a new algorithm or other cools features added. +Once the package is installed it should be accessible in your Python as `PyEMD`, e.g. :: + + >>> from PyEMD import EMD Research (github) ````````````````` diff --git a/setup.py b/setup.py index 4db4f1a..3123127 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -VERSION="0.2.15" +VERSION="1.0.0" DESCRIPTION = "Implementation of the Empirical Mode Decomposition (EMD) and its variations"