Skip to content

Commit

Permalink
Merge pull request #27 from derb12/2D
Browse files Browse the repository at this point in the history
ENH: Add 2D versions of several baseline algorithms
  • Loading branch information
derb12 authored Feb 13, 2024
2 parents d677d71 + 86fb254 commit c0f1057
Show file tree
Hide file tree
Showing 100 changed files with 13,174 additions and 917 deletions.
24 changes: 0 additions & 24 deletions .bumpversion.cfg

This file was deleted.

9 changes: 4 additions & 5 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
are required and/or what problems they fix. Link or add the issue number
for any existing issues that the pull request solves.
Note that unsolicited pull requests will most likely be closed.
Please file an issue first, so that details can be discussed/finalized
before a pull request is created.-->
Note that it is preferred to file an issue first, so that details can be
discussed/finalized before a pull request is created.-->


### Type of Pull Request
Expand All @@ -24,9 +23,9 @@ before a pull request is created.-->
To run tests locally, type the following command within the pybaselines
directory: pytest .
To lint files using flake8 to see if they pass PEP 8 standards and that
To lint files using ruff to see if they pass PEP 8 standards and that
docstrings are okay, run the following command within the pybaselines
directory: flake8 .
directory: ruff check .
To build documentation locally, type the following command within the
docs directory: make html
Expand Down
54 changes: 54 additions & 0 deletions .github/workflows/python-test-latest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# For testing the nightly builds of numpy and scipy so that any new changes will not be
# a surprise.

# Will only trigger if there is a change within pybaselines or tests directories.

name: test-latest-dependencies

on:
# allow manually activating the workflow
workflow_dispatch:

push:
branches: [ main ]
paths:
- 'pybaselines/**'
- 'tests/**'
- '.github/workflows/**'

pull_request:
# always trigger on a pull request, regardless of the branch
paths:
- 'pybaselines/**'
- 'tests/**'
- '.github/workflows/**'

jobs:
test-nightly:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Choose the latest stable python version
python-version: ['3.12']

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install required dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest
python -m pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy
python -m pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple scipy
- name: Test with required dependencies
# use -Werror so that any warnings will show up as errors -> want to be as stringent
# as possible
run: python -Werror -m pytest .
71 changes: 36 additions & 35 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,87 +26,88 @@ on:
jobs:
test:

runs-on: ubuntu-20.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Use strings since yaml considers 3.10 equal to 3.1
python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install required dependencies
run: |
python -m pip install --upgrade pip
python -m pip install "numpy>=1.14" "scipy>=1.0" pytest
# Only lint a single version; pick a recent, stable version
- name: Install linting dependencies
id: install-linters
if: matrix.python-version == '3.10'
run: |
python -m pip install flake8 flake8-comprehensions flake8-docstrings
- name: Lint
if: steps.install-linters.outcome == 'success'
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings.
flake8 . --count --exit-zero --statistics
python -m pip install "numpy>=1.20" "scipy>=1.5" pytest
- name: Test with required dependencies
run: pytest .

- name: Install optional dependencies
id: install-optional
# uncomment below in case this step ever needs skipped again
if: matrix.python-version != '3.12'
run: python -m pip install "pentapy>=1.0" "numba>=0.45"
# uncomment below to allow skipping future versions
#if: matrix.python-version != '3.13'
run: python -m pip install "pentapy>=1.0" "numba>=0.49"

- name: Test with optional dependencies
# uncomment below in case this step ever needs skipped again
if: steps.install-optional.outcome == 'success'
run: pytest .


test-min-dependencies:

runs-on: ubuntu-20.04
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.6']
python-version: ['3.8']

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install minimum dependencies
# Use numpy 1.14.5 rather than 1.14.0 since the optional
# dependency pentapy requires numpy>=1.14.5; no relevant difference
# between 1.14.0 and 1.14.5.
run: |
python -m pip install --upgrade pip
python -m pip install numpy==1.14.5 scipy==1.0 pytest
python -m pip install numpy==1.20 scipy==1.5 pytest
- name: Test with minimum required dependencies
run: pytest .

- name: Install minimum optional dependencies
# Have to pin llvmlite to 0.30.0 since it otherwise gets a more recent
# version that is imcompatible with numba v0.45
run: python -m pip install pentapy==1.0 numba==0.45 llvmlite==0.30.0
run: python -m pip install pentapy==1.0 numba==0.49

- name: Test with minimum optional dependencies
run: pytest .

lint:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.11']

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install linting dependencies
run: python -m pip install ruff

- name: Lint
run: ruff check . --show-source
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.9"
python: "3.11"

# Path to sphinx's configuration file
sphinx:
Expand Down
17 changes: 0 additions & 17 deletions MANIFEST.in

This file was deleted.

1 change: 0 additions & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python -msphinx
SPHINXPROJ = mcetl
SOURCEDIR = .
BUILDDIR = _build

Expand Down
34 changes: 18 additions & 16 deletions docs/_templates/autoapi/python/package.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,6 @@

{% endif %}

{% block subpackages %}
{% set visible_subpackages = obj.subpackages|selectattr("display")|list %}
{% if visible_subpackages %}
Subpackages
-----------
.. toctree::
:titlesonly:
:maxdepth: 3

{% for subpackage in visible_subpackages %}
{{ subpackage.short_name }}/index.rst
{% endfor %}


{% endif %}
{% endblock %}
{% block submodules %}
{% set visible_submodules = obj.submodules|selectattr("display")|list %}
{% if visible_submodules %}
Expand All @@ -47,6 +31,24 @@ Submodules

{% endif %}
{% endblock %}

{% block subpackages %}
{% set visible_subpackages = obj.subpackages|selectattr("display")|list %}
{% if visible_subpackages %}
Subpackages
-----------
.. toctree::
:titlesonly:
:maxdepth: 3

{% for subpackage in visible_subpackages %}
{{ subpackage.short_name }}/index.rst
{% endfor %}


{% endif %}
{% endblock %}

{% block content %}
{% if obj.all is not none %}
{% set visible_children = obj.children|selectattr("short_name", "in", obj.all)|list %}
Expand Down
16 changes: 8 additions & 8 deletions docs/algorithms/classification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Algorithms
dietrich (Dietrich's Classification Method)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`.dietrich` calculates the power spectrum of the data as the squared derivative
:meth:`~.Baseline.dietrich` calculates the power spectrum of the data as the squared derivative
of the data. Then baseline points are identified by iteratively removing points where
the mean of the power spectrum is less a multiple of the standard deviation of the
power spectrum. The baseline is created by first interpolating through all baseline
Expand Down Expand Up @@ -197,7 +197,7 @@ points, and then iteratively fitting a polynomial to the interpolated baseline.
golotvin (Golotvin's Classification Method)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`.golotvin` divides the data into sections and takes the minimum standard
:meth:`~.Baseline.golotvin` divides the data into sections and takes the minimum standard
deviation of all the sections as the noise's standard deviation for the entire data.
Then classifies any point where the rolling max minus min is less than a multiple of
the noise's standard deviation as belonging to the baseline.
Expand All @@ -224,7 +224,7 @@ the noise's standard deviation as belonging to the baseline.
std_distribution (Standard Deviation Distribution)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`.std_distribution` identifies baseline segments by analyzing the rolling
:meth:`~.Baseline.std_distribution` identifies baseline segments by analyzing the rolling
standard deviation distribution. The rolling standard deviations are split into two
distributions, with the smaller distribution assigned to noise. Baseline points are
then identified as any point where the rolled standard deviation is less than a multiple
Expand Down Expand Up @@ -253,8 +253,8 @@ of the median of the noise's standard deviation distribution.
fastchrom (FastChrom's Baseline Method)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`.fastchrom` identifies baseline segments by analyzing the rolling standard
deviation distribution, similar to :meth:`.std_distribution`. Baseline points are
:meth:`~.Baseline.fastchrom` identifies baseline segments by analyzing the rolling standard
deviation distribution, similar to :meth:`~.Baseline.std_distribution`. Baseline points are
identified as any point where the rolling standard deviation is less than the specified
threshold, and peak regions are iteratively interpolated until the baseline is below the data.

Expand All @@ -279,7 +279,7 @@ threshold, and peak regions are iteratively interpolated until the baseline is b
cwt_br (Continuous Wavelet Transform Baseline Recognition)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`.cwt_br` identifies baseline segments by performing a continous wavelet
:meth:`~.Baseline.cwt_br` identifies baseline segments by performing a continous wavelet
transform (CWT) on the input data at various scales, and picks the scale with the first
local minimum in the Shannon entropy. The threshold for baseline points is obtained by fitting
a Gaussian to the histogram of the CWT at the optimal scale, and the final baseline is fit
Expand Down Expand Up @@ -315,8 +315,8 @@ other points have a weight of 0.
fabc (Fully Automatic Baseline Correction)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:meth:`.fabc` identifies baseline segments by thresholding the squared first derivative
of the data, similar to :meth:`.dietrich`. However, fabc approximates the first derivative
:meth:`~.Baseline.fabc` identifies baseline segments by thresholding the squared first derivative
of the data, similar to :meth:`~.Baseline.dietrich`. However, fabc approximates the first derivative
using a continous wavelet transform with the Haar wavelet, which is more robust to noise
than the numerical derivative in Dietrich's method. The baseline is then fit using
Whittaker smoothing with all baseline points having a weight of 1 and all other points
Expand Down
20 changes: 14 additions & 6 deletions docs/algorithms/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@
Algorithms
==========

The currently available baseline correction algorithms in pybaselines are split into
polynomial, whittaker, morphological, smooth, spline, classification, optimizers,
and miscellaneous (misc). Note that this is more for grouping code and not meant as
a hard-classification of the algorithms.
The currently available baseline correction algorithms in pybaselines can broadly be categorized
as polynomial, whittaker, morphological, smooth, spline, classification, optimizers,
and miscellaneous (misc) methods. Note that this is simply for grouping code and helping to
explain the internals of this library and **NOT** meant as a hard-classification of the
field of baseline correction (Please stop blindly copying this section in papers. There are
numerous types of baseline correction algorithms that are not included within pybaselines, which
is why baseline correction in general is such an absolutely fascinating field! Besides, miscellaneous
is obviously not an actual type of baseline correction...)

This section of the documentation is to help provide some context for each algorithm.
In addition, most algorithms will have a figure that shows how well the algorithm fits
various baselines to help choose the correct algorithm for a particular baseline. Refer
to the :doc:`API section <../api/index>` of the documentation for the full parameter and
various datasets to help choose the correct algorithm for a particular baseline. These datasets
include noisy data, data with both positive and negative peaks, data with overlapping peaks,
and concave data, and they serve as a way to quickly filter out algorithms that would not
work for a particular dataset.

Refer to the :doc:`API section <../api/index>` of the documentation for the full parameter and
reference listing for any algorithm.


Expand Down
Loading

0 comments on commit c0f1057

Please sign in to comment.